Hi !
I wrote a little app in python that downloads Calvin & Hobbes comics from the web and displays them on the N800.
I use a little "animation" as a transition between strips. However since i'm really new to pygame my implementation is probably very bad. So i was hoping someone here could point out how to make the animation smoother.
Thanks!
Keys:
Back -> Exit
Fullscreen -> Toggles Fullscreen (also app is made for fullscreen)
zoomin/out -> toggle scaling
d-pad center: next strip
d-pad right: next strip with animation
http://www.vdecine.net/Calvin.tar.gz
twaelti
08-19-2007, 04:23 PM
Hello Zeez
Thank you very much for your wonderful little app - it finally motivated me to start Python dev on the N800 :)
From what I picked up about PyGame, one possible way to improve the performance of the animation would be to use the Sprite module of PyGame, handling the two strips as sprites. Hadn't yet time to test this.
In the meantime, I made 4 modifications to your code:
Animation comes in from right to left now (seems more natural)
Strips change automaticall every 5 seconds. D-Pad Down to disable/enable (status icon shows red/green in topleft corner)
Reset strips and show first one: D-Pad Up ((status icon shows blue in topleft corner)
Touching the screen moves to the next strip, too (just like D-Pad Right)
Another minor optimisation you could do: Re-compress the included status images , they are way too big for what they contain. You might safely compress them much more with JPEG.
Ah the joy of coding.
Thanks again, mate!
#!/usr/bin/python
import pygame
from pygame.locals import *
import os
import urllib
import time
import datetime
import thread
EVT_STEP = pygame.USEREVENT
path = './strips/'
bTimerRunning = False
# Class that handles the strip "database"
class strips:
def __init__(self):
self.availableStrips = []
self.readStrips = self.loadReadStrips()
self.currentStrip = ''
# Get list of read strips from file
def loadReadStrips(self):
read = []
for line in open('read.log','rw').readlines():
line=line[0:len(line)-1]
if (line!=''):
read.append(line)
return read
# Save current list of read strips to file
def saveReadStrips(self):
file = open('read.log', 'w')
for strip in self.readStrips:
file.write(strip + '\n')
# Save current list of read strips to file
def resetReadStrips(self):
self.readStrips = []
self.availableStrips = []
file = open('read.log', 'w')
file.write('\n')
self.get()
self.currentStrip = self.getFirst()
return self.currentStrip
# Locally save a strip from the web
def saveUrlToFile(self, url, fileName):
try:
f = open( fileName, 'wb' )
data = urllib.urlopen(url).read()
f.write( data )
f.close()
return 1
except:
return 0
# Get available strips
def get(self):
now = datetime.date.today()
today = now.strftime("%y%m%d")
for i in range(30): # Usually there are strips avail. for the last 30 days
delta = datetime.timedelta(days=-i)
now2 = now + delta
date = now2.strftime("%y%m%d")
if ('ch' + date + '.gif' not in self.readStrips): # Make sure strip has not been read
if (os.path.isfile(path + 'ch' + date + '.gif') and os.path.getsize(path + 'ch' + date + '.gif') > 5000):
self.availableStrips.append('ch' + date + '.gif')
elif(self.saveUrlToFile('http://images.ucomics.com/comics/ch/2007/ch' + date + '.gif',path + 'ch' + date + '.gif')):
self.availableStrips.append('ch' + date + '.gif')
# Return the next unread strip (which is the oldest unread)
def getNext(self):
if (len(self.availableStrips) > 0):
self.currentStrip = self.availableStrips.pop()
self.readStrips.append(self.currentStrip)
return self.currentStrip
else:
return 'nomore.jpg'
# Return the first unread strip
def getFirst(self):
if (len(self.availableStrips) > 0):
self.currentStrip = self.availableStrips[0]
return self.currentStrip
else:
return 'nomore.jpg'
# Class that handles all display stuff
class display:
def __init__(self):
pygame.init()
self.scale = False
self.screen = pygame.display.set_mode((800,480),FULLSCREEN,16)
self.back = pygame.image.load(os.path.join(".","chback.gif"))
# Let the user know we're downloading the strips
def showLoading(self):
load = pygame.image.load(os.path.join(".","loading.jpg")).convert()
self.screen.blit(load,(0,0))
pygame.display.flip()
# Load file and return surface
def loadFile(self,file):
try:
strip = pygame.image.load(os.path.join(path, file)).convert()
if (self.scale==True):
if (strip.get_height() > 200):
strip = pygame.transform.scale(strip, (691,480))
else:
strip = pygame.transform.scale(strip, (800,252))
except:
strip = pygame.image.load(os.path.join('.', 'nomore.jpg')).convert()
return strip
# Show a strip without anymation (currently just the first one)
def showStrip(self,strip):
stripSur = self.loadFile(strip)
self.screen.blit(self.back,(0,0))
self.screen.blit(stripSur,((800-stripSur.get_width())/2,(480-stripSur.get_height())/2))
pygame.display.flip()
def switchStrips(self,strip1,strip2):
strip1Sur = self.loadFile(strip1)
strip2Sur = self.loadFile(strip2)
for x in range(81):
self.screen.blit(self.back,(0,0))
# self.screen.blit(strip1Sur,((800-strip1Sur.get_width())/2+10*x,(480-strip1Sur.get_height())/2))
# self.screen.blit(strip2Sur,((((800-strip2Sur.get_width())/2)+10*x)-800,(480-strip2Sur.get_height())/2))
self.screen.blit(strip1Sur,(((800-strip1Sur.get_width())/2+10*x)*-1,(480-strip1Sur.get_height())/2))
self.screen.blit(strip2Sur,((((800-strip2Sur.get_width())/2)-10*x)+800,(480-strip2Sur.get_height())/2))
pygame.display.flip()
def animatedTransition(self, s, d):
s.saveReadStrips()
d.showStrip(s.getNext())
def SwitchTimer(self,bTimer):
if(bTimer == True):
pygame.time.set_timer(EVT_STEP, 0)
bTimer = False
color = (255, 128, 128)
else:
pygame.time.set_timer(EVT_STEP, 10000)
bTimer = True
color = (128, 255, 128)
statusIcon = pygame.Surface((10, 10))
statusIcon.fill(color)
self.screen.blit(statusIcon, (10,10))
pygame.display.flip()
return bTimer
if __name__ == '__main__':
s = strips()
d = display()
# Check for new strips
d.showLoading()
s.get()
# Show the first one automatically
d.showStrip(s.getNext())
#start the timer
bTimerRunning = d.SwitchTimer(bTimerRunning)
#disable the cursor
pygame.mouse.set_visible(False)
# Wait for user input
while True:
event = pygame.event.wait()
if (event.type == KEYUP):
if (event.key == 287): # Fullscreen button / F6 : Toggle fullscreen
pygame.display.toggle_fullscreen()
if (event.key != K_ESCAPE): # Esc/Back button -> Exit
if (event.key == 13): # DPad-center -> show next strip
s.saveReadStrips()
d.showStrip(s.getNext())
if (event.key == 275): # DPad-right -> show next strip (animated)
s.saveReadStrips()
d.switchStrips(s.currentStrip,s.getNext())
if (event.key == 274): # DPad-down -> enable/disable timer
bTimerRunning = d.SwitchTimer(bTimerRunning)
if (event.key == 273): # DPad-up -> restart fro 1st picture, reset list
color = (128, 128, 255)
statusIcon = pygame.Surface((10, 10))
statusIcon.fill(color)
d.screen.blit(statusIcon, (10,10))
pygame.display.flip()
d.showStrip(s.resetReadStrips())
if (event.key == 289): # Zoom out -> No Scale
d.scale = False
d.showStrip(s.currentStrip)
if (event.key == 288): # Zoom in -> Scale strips to screen
d.scale = True
d.showStrip(s.currentStrip)
else:
break
if (event.type == EVT_STEP): #Timer-Event
s.saveReadStrips()
d.switchStrips(s.currentStrip,s.getNext())
if (event.type == MOUSEBUTTONDOWN): #Touchscreen-Event
s.saveReadStrips()
d.switchStrips(s.currentStrip,s.getNext())
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.