-
-
Save anonymous/278158f70872b37f70df to your computer and use it in GitHub Desktop.
ex_walk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#example of animated frames for a character walk. | |
#downloads a soldier sprite sheet, cuts out frames for the walk cycles in 4 directions | |
# and animates the character walking in the direction controlled by gravity. | |
from scene import * | |
from PIL import Image | |
import urllib, os | |
from random import randint | |
start = Point(2, 1) #the sheet has 8 sets of characters in a 4x2 grid. | |
startMons = Point(1, 1) | |
ssize = Size(96, 128) | |
speed = 0.15 | |
speedMonsters = 0.15 | |
boost = 10 | |
frames = [0, 1, 2, 1] #4 frames per walk cycle | |
dirs = [0, 3, 9, 6] #start frame for direction | |
moveamt = 32 | |
mov = [(0, -moveamt), (-moveamt, 0), (0, moveamt), (moveamt, 0)] | |
keycolor = (0, 255, 0, 255) | |
gravsense = 0.06 | |
north = 0 | |
south = 2 | |
east = 1 | |
west = 3 | |
hitRange=10 | |
class collision (object): | |
def __init__(self, location, size, type): | |
self.location = location | |
self.size = size | |
self.type=type | |
class monster (object): | |
def __init__(self, location, size, type): | |
self.location = location | |
self.size = size | |
self.type=type | |
self.dir=0 | |
self.start = 0 | |
self.delay = speedMonsters | |
self.movlen = 0 #how long until randomly changes dir | |
def score(self): | |
tint(0,1,1,1) | |
s='Score: '+str(self.score)+' Lives: '+str(self.lives) | |
text(s, 'Futura', 40, *self.bounds.center().as_tuple()) | |
tint(1,1,1,1) | |
def hitTest(x1,y1,size1,x2,y2,size2,output=0): | |
if x1+size1>=x2 and x1<=x2+size2: | |
if y1+size1>=y2 and y1<=y2+size2: | |
output=1 | |
if output: | |
#Calculate origins | |
ox1=x1+(size1/2) | |
oy1=y1+(size1/2) | |
ox2=x2+size2/2 | |
oy2=y2+size2/2 | |
#Difference between origins to locate the direction | |
difx=ox1-ox2 | |
dify=oy1-oy2 | |
if difx<=0: output1=1#hit from r | |
else: output1=2#hit from l | |
if dify<=0: output2=1#hit from t | |
else: output2=2#hit from b | |
#check which is most important | |
if dify<0:dify*=-1 | |
if difx<0:difx*=-1 | |
if difx>dify: output=output1 | |
else: output=output2+2 | |
return output | |
def hitTest2(loc1,size1,loc2,size2,output=0): | |
if loc1.x+size1.x>=loc2.x and loc1.x<=loc2.x+size2.x: | |
if loc1.y+size1.y>=loc2.y and loc1.y<=loc2.y+size2.y: | |
output=1 | |
if output: | |
#Rectangle alert | |
#Calculate origins | |
ox1=loc1.x+size1.x/2 | |
oy1=loc1.y+size1.y/2 | |
ox2=loc2.x+size2.x/2 | |
oy2=loc2.y+size2.y/2 | |
#Difference between origins to locate the direction | |
difx=ox1-ox2 | |
dify=oy1-oy2 | |
if difx<=0: output1=1#hit from r | |
else: output1=2#hit from l | |
if dify<=0: output2=1#hit from t | |
else: output2=2#hit from b | |
#check which is most important | |
if dify<0:dify*=-1 | |
if difx<0:difx*=-1 | |
print '...' | |
print difx | |
print dify | |
if difx>dify: output=output1 | |
else: output=output2+2 | |
#output=output2+2 | |
return output | |
def wrap(v, ext): | |
if v < 0: | |
return ext + v | |
elif v >= ext: | |
return v - ext | |
return v | |
def reverseDir(dir): | |
if dir==0: dir=2 | |
elif dir==1: dir=3 | |
elif dir==2: dir=0 | |
else: dir=1 | |
return dir | |
def gravitydirections(dir): | |
ax = abs(dir.x) | |
ay = abs(dir.y) | |
dx = 0 | |
dy = 0 | |
#If x is larger than the sensitivity then set east or west. | |
if ax > gravsense: | |
dx = west if dir.x > 0 else east | |
#If y is larger than the sensitivity then set north or south. | |
if ay > gravsense: | |
dy = south if dir.y > 0 else north | |
#return direction tuple in order of largest gravity direction. | |
return dy if ay > ax else dx | |
def touchdirections(dir,source): | |
dx=dir.x-source.x | |
dy=dir.y-source.y | |
if dx<0:dx*=-1 | |
if dy<0:dy*=-1 | |
if dx>dy: | |
if dir.x > source.x: output=3 | |
else: output=1 | |
else: | |
if dir.y>source.y: output=2 | |
else: output=0 | |
return output | |
class MyScene (Scene): | |
def setup(self): | |
# This will be called before the first frame is drawn. | |
if not os.path.exists('Images'): | |
os.mkdir('Images') | |
if not os.path.exists("Images/soldier2.png"): | |
url = urllib.urlopen('http://img63.imageshack.us/img63/4348/americanset.png') | |
with open("Images/soldier2.png", "wb") as output: | |
output.write(url.read()) | |
img = Image.open("Images/soldier2.png").convert('RGBA') | |
#img.show() | |
strt = Point(start.x * ssize.w, start.y * ssize.h) | |
img1 = img.crop((strt.x, strt.y,strt.x + ssize.w - 1, strt.y + ssize.h - 1)) | |
d = img1.load() | |
keycolor = d[0,0] #1st pixel is used as keycolor. | |
for x in range(img1.size[0]): | |
for y in range(img1.size[1]): | |
p = d[x, y] | |
if p == keycolor: #if keycolor set alpha to 0. | |
d[x, y] = (p[0], p[1], p[2], 0) | |
img1.show() | |
strt2 = Point(startMons.x * ssize.w, startMons.y * ssize.h) | |
img2 = img.crop((strt2.x, strt2.y,strt2.x + ssize.w - 1, strt2.y + ssize.h - 1)) | |
d2 = img2.load() | |
keycolor = d2[0,0] #1st pixel is used as keycolor. | |
for x in range(img2.size[0]): | |
for y in range(img2.size[1]): | |
p = d2[x, y] | |
if p == keycolor: #if keycolor set alpha to 0. | |
d2[x, y] = (p[0], p[1], p[2], 0) | |
img2.show() | |
def getframe(x, y, mons): | |
if mons==0: | |
nim = img1.crop((x * 32, y * 32, (x+1) * 32, (y+1) * 32)) | |
else: nim = img2.crop((x * 32, y * 32, (x+1) * 32, (y+1) * 32)) | |
# nim = nim.resize((16,16), Image.ANTIALIAS) | |
return load_pil_image(nim) | |
self.images = [getframe(x,y,0) for y in xrange(4) for x in xrange(3)] | |
self.imagesMons=[getframe(x,y,1) for y in xrange(4) for x in xrange(3)] | |
self.start = 0 | |
self.base = 0 | |
self.dir = 0 | |
self.score=0 | |
self.lives=3 | |
self.delay = speed | |
self.x = 400 | |
self.y = 400 | |
self.target=Point(400,400) | |
self.collisions=set() #set up collision objects like walls | |
box=collision(Point(100,200),Point(100,100),0) | |
self.collisions.add(box) | |
box=collision(Point(100,400),Point(50,200),1) | |
self.collisions.add(box) | |
box=collision(Point(330,300),Point(100,400),2) | |
self.collisions.add(box) | |
self.monsters=set() #set up monsters | |
#mons=monster(Point(300,400),Point(32,32),1) | |
#self.monsters.add(mons) | |
def touch_moved(self, touch): | |
self.dir = touchdirections(touch.location,self) | |
global speed | |
speed = .25 | |
d = self.dir | |
def touch_ended(self, touch): | |
self.dir = touchdirections(touch.location,self) | |
global speed | |
speed = .25 | |
self.target.x=touch.location.x | |
self.target.y=touch.location.y | |
#mons=monster(Point(300,400),Point(32,32),1) | |
#self.monsters.add(mons) | |
#box=collision(Point(randint(0,500),200),Point(100,100),randint(0,1)) | |
#self.collisions.add(box) | |
def draw(self): | |
# This will be called for every frame (typically 60 times per second). | |
#self.dir = gravitydirections(gravity()) | |
global speed | |
background(1, 1, 1) | |
score(self) | |
d = self.dir | |
mv = mov[d] | |
if self.target.x>self.x+hitRange or self.target.x<self.x-hitRange: | |
speed=.2 | |
if self.target.x>self.x+hitRange:self.dir=3 | |
else:self.dir=1 | |
#self.dir=touchdirections(self.target,self) | |
#self.dir=0#self.dir | |
#mv = mov[d] | |
self.x += mv[0] *boost* self.dt | |
self.x = wrap(self.x, self.size.w) | |
elif self.target.y>self.y+hitRange or self.target.y<self.y-hitRange: | |
speed=.2 | |
self.dir=touchdirections(self.target,self) | |
d = self.dir | |
#mv = mov[d] | |
self.y += mv[1] *boost* self.dt | |
self.y = wrap(self.y, self.size.h) | |
else: speed=.4 | |
self.delay -= self.dt | |
if self.delay <= 0: | |
self.delay += speed | |
self.start += 1 | |
if self.start >= len(frames): self.start = 0 | |
dead=set() | |
for z in self.collisions: | |
if z.type==0: fill(0,0,1) | |
elif z.type==1: fill(1,0,0) | |
else: fill(0,1,0) | |
rect(z.location.x,z.location.y,z.size.x,z.size.y) | |
hitz=hitTest2(Point((self.x+moveamt/3),(self.y+moveamt/3)),Point(hitRange,hitRange),z.location,z.size) | |
#hitz=hitTest2(z.location,z.size,Point((self.x+moveamt/3),(self.y+moveamt/3)),Point(hitRange,hitRange)) | |
if hitz!=0: | |
if z.type==0: | |
self.y+=boost | |
elif z.type==1: #glitchy pythonista | |
self.y-=boost | |
else: | |
print hitz | |
if hitz==1: | |
#self.x-=10 | |
z.location.x+=10 | |
elif hitz==2: z.location.x-=10 | |
elif hitz==3: z.location.y+=10 | |
elif hitz==4: z.location.y-=10 | |
self.target.x=self.x | |
self.target.y=self.y | |
for m in self.monsters: | |
if hitTest2(z.location,z.size,m.location,m.size): | |
#dead.add(m) | |
m.dir=reverseDir(m.dir) | |
#z.location.x-=10 | |
#print z | |
fill(0,0,0) | |
for m in self.monsters: | |
m.movlen+=1 | |
if m.movlen>100: | |
m.movlen=0 | |
m.dir=randint(0,3) | |
dm=m.dir | |
mvm=mov[dm] | |
#print self.dt | |
#print mvm | |
m.location.x += mvm[0] *1* self.dt | |
m.location.x = wrap(m.location.x, self.size.w) | |
m.location.y += mvm[1] *1* self.dt | |
m.location.y = wrap(m.location.y, self.size.h) | |
m.delay -= self.dt | |
if m.delay <= 0: | |
m.delay += speedMonsters | |
m.start += 1 | |
if m.start >= len(frames): m.start = 0 | |
image(self.imagesMons[dirs[m.dir] + frames[m.start]], | |
m.location.x, m.location.y, 32, 32) | |
#rect(m.location.x,m.location.y,m.size.x,m.size.y) | |
hit=hitTest2(Point(self.x+moveamt/3,self.y+moveamt/3),Point(hitRange,hitRange),m.location,m.size) | |
if hit!=0: | |
dead.add(m) | |
#print hit | |
#m.dir=reverseDir(m.dir) | |
self.monsters-=dead | |
self.score+=len(dead) | |
#if len(self.monsters)<1: | |
#mons=monster(Point(300,400),Point(32,32),1) | |
#self.monsters.add(mons) | |
image(self.images[dirs[d] + frames[self.start]], self.x, self.y, 32, 32) | |
run(MyScene())#, PORTRAIT) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment