设为首页 收藏本站
查看: 739|回复: 0

[经验分享] Python逃生游戏

[复制链接]

尚未签到

发表于 2015-10-26 13:21:36 | 显示全部楼层 |阅读模式
  从<趣学Python编程>上看到的例子,小人在石头上跑跳直到达到门
  我做了以下改进:
  1. 模块化:
  


  • helper.py 含有基类以及碰撞检测函数
  • man.py 小人
  • door,py 门
  • stone.py 脚踩的石头
  • game.py 主函数,初始化canvas,游戏主循环

2. 修复一个Bug,原先人踩在石头上会掉下来
if btm and falling and self.y == 0 \

and (co.y2 >= self.game.canvas_h \

or collide_bottom(1, co, s_co)): #man stand on the stone

falling = False

  
  素材:
  背景bg.gif    DSC0000.jpg
  门d_1.gif    DSC0001.jpg
  跑动的小人
  man_l_1   DSC0002.jpg
  man_l_2   DSC0003.jpg
  man_l_3 DSC0004.jpg
  man_r_1 DSC0005.jpg
  man_r_2 DSC0006.jpg
  man_r_3 DSC0007.jpg
  


  模块化代码:
  helper.py
  #Object
class Sprite:
def __init__(self, game):
self.game = game
self.endGame = False
self.co = None
def move(self):
pass
def coords(self):
return self.co

class Coords:
def __init__(self, x1 = 0, y1 = 0, x2 = 0, y2 = 0):
self.x1 = x1
self.x2 = x2
self.y1 = y1
self.y2 = y2
#intersection
def inter_x(co1, co2):
if (co1.x1 >= co2.x2) or (co1.x2 <= co2.x1):
return False
else:
return True
def inter_y(co1, co2):
if (co1.y1 >= co2.y2) or (co1.y2 <= co2.y1):
return False
else:
return True
def collide_left(co1, co2):
if inter_y(co1,co2) and co1.x1 <= co2.x2 and co1.x1 >= co2.x1:
return True
return False
def collide_right(co1, co2):
if inter_y(co1,co2) and co1.x2 <= co2.x2 and co1.x2 >= co2.x1:
return True
return False
def collide_top(co1, co2):
if inter_x(co1,co2) and co1.y1 <= co2.y2 and co1.y1 >= co2.y1:
return True
return False
def collide_bottom(y, co1, co2):
y = co1.y2 + y
if inter_x(co1,co2) and y <= co2.y2 and y >= co2.y1:
return True
return False


stone.py
  from helper import *
class Stone(Sprite):
def __init__(self, game, x, y, w, h):
Sprite.__init__(self, game);#call father
self.image = game.canvas.create_rectangle(x, y, x + w, y + h, fill='pink')
self.co = Coords(x, y, x + w, y + h)

door.py
  from helper import *
from tkinter import *
class Door(Sprite):
def __init__(self, game, x, y):
Sprite.__init__(self, game);#call father
self.photo_image = PhotoImage(file = 'd_1.gif');
self.image = game.canvas.create_image(x, y, image = self.photo_image, anchor = 'nw')
self.co = Coords(x, y, x + 27, y + 30)
self.endGame = True

man.py
  from helper import *
import time
from tkinter import *
class Man(Sprite):
def __init__(self, game):
Sprite.__init__(self, game);#call father
self.image_l = [
PhotoImage(file=&quot;man_l_1.gif&quot;),
PhotoImage(file=&quot;man_l_2.gif&quot;),
PhotoImage(file=&quot;man_l_3.gif&quot;)
]
self.image_r = [
PhotoImage(file=&quot;man_r_1.gif&quot;),
PhotoImage(file=&quot;man_r_2.gif&quot;),
PhotoImage(file=&quot;man_r_3.gif&quot;)
]
self.image = game.canvas.create_image(0, 0, image=self.image_l[0], anchor='nw')
self.x = -2
self.y = 0
self.current_img = 0#image index
self.current_img_add = 1
self.jump_count = 0#use for jump
self.last_time = time.time()
self.co = Coords()
game.canvas.bind_all(&quot;<Key-Left>&quot;, self.turn_left)
game.canvas.bind_all(&quot;<Key-Right>&quot;, self.turn_right)
game.canvas.bind_all(&quot;<Key-space>&quot;, self.jump)
def turn_left(self, evt):
#if self.y == 0:
self.x = -2
def turn_right(self, evt):
#if self.y == 0:
self.x = 2
def jump(self, evt):
if self.y == 0:
self.y = -4
self.jump_count = 0
#important change img of Man
def animate(self):
if self.x != 0 and self.y == 0:
if time.time() - self.last_time > 0.1:  #change img slowly
self.last_time = time.time()
self.current_img += self.current_img_add
if self.current_img >= 2:
self.current_img_add = -1
elif self.current_img <= 0:
self.current_img_add = 1
if self.x < 0:
if self.y != 0:
self.game.canvas.itemconfig(self.image, \
image = self.image_l[2])
else:
self.game.canvas.itemconfig(self.image, \
image = self.image_l[self.current_img])
if self.x > 0:
if self.y != 0:
self.game.canvas.itemconfig(self.image, \
image = self.image_r[2])
else:
self.game.canvas.itemconfig(self.image, \
image = self.image_r[self.current_img])
def coords(self):
xy = self.game.canvas.coords(self.image)
self.co.x1 = xy[0]
self.co.y1 = xy[1]
self.co.x2 = xy[0] + 27
self.co.y2 = xy[1] + 30
return self.co
#important
def move(self):
self.animate()
#for jump case, update y
if self.y < 0:
self.jump_count = self.jump_count + 1
if self.jump_count > 20:
self.y = 4
elif self.y > 0:
self.jump_count = self.jump_count - 1
#collision check
co = self.coords()
left = True
right = True
top = True
btm = True
falling = True
#1.collide with canvas
if self.y > 0 and co.y2 >= self.game.canvas_h:
self.y = 0
btm = False
elif self.y < 0 and co.y2 <= 0:
self.y = 0
top = False
if self.x > 0 and co.x2 >= self.game.canvas_w:
self.x = 0
right = False
elif self.x < 0 and co.x2 <= 0:
self.x = 0
left = False
#2.collide with stone
for s in self.game.sprites:
if s == self:
continue
s_co = s.coords()
if top and self.y < 0 and collide_top(co, s_co):#collide top
self.y = - self.y
top = False
if btm and self.y > 0 and collide_bottom(self.y, co, s_co):#collide btm
#self.y = s_co.y1 - co.y2
#if self.y < 0:
self.y = 0
btm = False
top = False
if btm and falling and self.y == 0 \
and (co.y2 >= self.game.canvas_h \
or collide_bottom(1, co, s_co)): #man stand on the stone
falling = False
if left and self.x < 0 and collide_left(co, s_co):#collide left
self.x = 0
left = False
if s.endGame:#if s is door
self.game.running = False
if right and self.x > 0 and collide_right(co, s_co):#collide right
self.x = 0
right = False
if s.endGame:#if s is door
self.game.running = False
print (&quot;btm is %s&quot; % btm);
#let the man fall
if falling and btm and self.y == 0\
and co.y2 < self.game.canvas_h:
self.y = 4
self.game.canvas.move(self.image, self.x, self.y)

game.py
  from tkinter import *
import random
from stone import *
from man import *
from door import *
#Game controller
class Game:
def __init__(self):
self.tk = Tk()
self.tk.title(&quot;Run away from gost house&quot;)
self.tk.resizable(0,0)
self.tk.wm_attributes(&quot;-topmost&quot;, 1)
self.canvas = Canvas(self.tk, width = 500, height = 500, highlightthickness=0)
self.canvas.pack()
self.tk.update()
self.canvas_h = 500
self.canvas_w = 500
self.bg = PhotoImage(file=&quot;bg.gif&quot;)
w = self.bg.width()
h = self.bg.height()
for x in range(0,5):
for y in range(0,5):
self.canvas.create_image( x * w, y * h, image=self.bg, anchor='nw')
self.sprites = []
self.running = True
def loop(self):
while 1:
if self.running:
for sprite in self.sprites:
sprite.move()
self.tk.update_idletasks()
self.tk.update()
time.sleep(0.01)

g = Game()
for i in range(60, 500, 30):
x = random.randint(0, 450)
y = random.randint(-5, 5)
width = random.randint(40, 100)
g.sprites.append(Stone(g, x, i + y, width, 10))
#door
door = Door(g, 50, 300)
g.sprites.append(door)
lastStone = Stone(g, 50, 300, 60, 10)
g.sprites.append(lastStone)
m = Man(g)
g.sprites.append(m)
g.loop()






版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-131003-1-1.html 上篇帖子: Python 中的 unit test 流程 下篇帖子: (linux)python之setuptools、easyinstall、pip安装及连接redis
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表