wxpython贪食蛇(练手项目2)

      贪食蛇不是fps,没有那么高的效率,不可能更新窗口里面的全部内容,这样就需要一个算法来处理这个问题,

算法:假设小蛇由一个蛇头,n个蛇身组成,整个蛇的前进由蛇头控制,方向由用户控制。

每次刷新时,从蛇尾开始遍历,把(n-1)方块的位置赋给n方块,直到n为1,最后将蛇头的位置赋给0方块。

显示时不需更新窗口中每一个图片,如果蛇总共(n+1)个方块,则只需更新(n+2)个方块,(n+1)个蛇方块当然更新,还有一个就是这一次蛇腾出来的空间(即上一次蛇尾的位置)用土地本来的图片替换,这样整个蛇就会跟着蛇头跑不会留下痕迹。

实现了一个基本功能版,靠(wasd)控制方向,里面会随机出现蛋糕,吃掉蛋糕会得分,并且增长蛇身,碰到边界游戏结束

不到200行就搞定了,需要图片在附件

#-*- coding:utf-8 -*-
'''
Created on 2011-3-23
经典游戏 --贪食蛇
@author: 123
'''

import wx
import random,time

#蛇身方块
class westiceSnakeBody():
    def __init__(self):
        randnum=int(random.random()*4)
        imagename='snakeskin'+str(randnum)+'.jpg'
        img1=wx.Image(imagename,wx.BITMAP_TYPE_ANY)
        self.img1=img1.Scale(30,30)#2 缩小图像
        self.x=-1
        self.y=-1

#蛇体
class westiceSnake():
    def __init__(self):
        self.bodys=[]
        self.headx=int(random.random()*(10))+5
        self.heady=int(random.random()*(10))+5
        self.direct=int(random.random()*4)
        self.img1=wx.Image('snakehead.jpg',wx.BITMAP_TYPE_ANY)
        self.headimg90=self.img1.Rotate90(True)
        self.headimg180=self.headimg90.Rotate90(True)
        self.headimg_90=self.img1.Rotate90(False)
        self.headimg1=self.img1
        self.prev_snakex=self.headx
        self.prev_snakey=self.heady
    def update(self):#更新
        #保存小蛇前一时刻最后一个位置
        if len(self.bodys)!=0:
            self.prev_snakex=self.bodys[len(self.bodys)-1].x
            self.prev_snakey=self.bodys[len(self.bodys)-1].y
        else:
            self.prev_snakex=self.headx
            self.prev_snakey=self.heady
        
        if len(self.bodys)!=0:
            for index in range(len(self.bodys)-1,0,-1):
                self.bodys[index].x=self.bodys[index-1].x
                self.bodys[index].y=self.bodys[index-1].y
            self.bodys[0].x=self.headx
            self.bodys[0].y=self.heady        
        #移动小蛇
        if self.direct==0:
            self.headx+=1#向右
        if self.direct==1:
            self.heady+=1#向下
        if self.direct==2:
            self.headx-=1#向左
        if self.direct==3:
            self.heady-=1#向上
        #旋转一下蛇头
        self.headimg1=self.img1
        if self.direct==0:
            self.headimg1=self.headimg90
        if self.direct==1:
            self.headimg1=self.headimg180
        if self.direct==2:
            self.headimg1=self.headimg_90
        self.headimg1=self.headimg1.Scale(30,30)

#游戏主窗口
class MyFrame(wx.Frame):
    gridwidth=20
    gridheight=20
    landsqurelist=[]
    first=True
    def __init__(self):
        wx.Frame.__init__(self,None,-1,"My Frame",size=(800,700))
        self.panel=wx.Panel(self,-1)
        self.score=0
        self.scoretxt=wx.StaticText(self.panel,-1,'得分:'+str(self.score),pos=(630,300))
        self.gamestatustxt=wx.StaticText(self.panel,-1,'游戏状态:正在运行',pos=(630,350))
        fgs=wx.FlexGridSizer(cols=self.gridwidth,hgap=0,vgap=0)
        self.panel.Bind(wx.EVT_KEY_DOWN,self.OnKeyDown)
        self.panel.SetFocus()
        for col in range(self.gridwidth):
            random.seed(time.time())
            for row in range(self.gridheight):
                
                #加载草地 
                randnum=int(random.random()*4)
                #随即加蛋糕
                if random.random()<0.02:
                    randnum=-1
                imagename='land'+str(randnum)+'.jpg'
                img1=wx.Image(imagename,wx.BITMAP_TYPE_ANY)
                img1=img1.Scale(30,30)#2 缩小图像
                sb1=wx.StaticBitmap(self.panel,-1,wx.BitmapFromImage(img1))
                sb1.randnum=randnum #存入图片名
                fgs.Add(sb1)
                self.landsqurelist.append(sb1)
        self.panel.SetSizerAndFit(fgs)
        
        #生成蛇,初始化位置,
        self.westicesnake=westiceSnake()

        #设定一个时钟
        self.timer1=wx.Timer(self)
        self.Bind(wx.EVT_TIMER,self.frameUpdate,self.timer1)
        self.timer1.Start(500) #可在此设置速度
    
    #键盘绑定
    def OnKeyDown(self,event):
        if ord('A')==event.GetKeyCode()and self.westicesnake.direct!=0:
            #向左
            self.westicesnake.direct=2
        if ord('D')==event.GetKeyCode()and self.westicesnake.direct!=2:
            #向右
            self.westicesnake.direct=0
        if ord('S')==event.GetKeyCode()and self.westicesnake.direct!=3:
            #向下
            self.westicesnake.direct=1
        if ord('W')==event.GetKeyCode()and self.westicesnake.direct!=1:
            #向上
            self.westicesnake.direct=3
        
    #帧更新
    def frameUpdate(self,event):
        
        #游戏算法实现处
        if self.westicesnake.headx>=0and self.westicesnake.headx<self.gridwidth\
           and self.westicesnake.heady>=0and self.westicesnake.heady<self.gridheight:
            tempindex=self.getIndex(self.westicesnake.headx,self.westicesnake.heady)
            #显示蛇头
            self.landsqurelist[tempindex].SetBitmap(wx.BitmapFromImage(self.westicesnake.headimg1))
            #显示小蛇身体                
            for body in self.westicesnake.bodys:
                tempindex=self.getIndex(body.x,body.y)
                self.landsqurelist[tempindex].SetBitmap(wx.BitmapFromImage(body.img1))   
            #显示上一次腾出的位置
            if not self.first:
                tempindex=self.getIndex(self.westicesnake.prev_snakex,self.westicesnake.prev_snakey)
                tempimagenum=self.landsqurelist[tempindex].randnum
                tempimagename='land'+str(tempimagenum)+'.jpg'
                img1=wx.Image(tempimagename,wx.BITMAP_TYPE_ANY)
                img1=img1.Scale(30,30)
                self.landsqurelist[tempindex].SetBitmap(wx.BitmapFromImage(img1))
            else:
                self.first=False
             
            
            #遇到蛋糕吃下,长蛇身,将蛋糕换成land
            if self.landsqurelist[tempindex].randnum==(-1):
                print '吃蛋糕'
                self.score+=1
                self.scoretxt.SetLabel('得分:'+str(self.score))
                self.landsqurelist[tempindex].randnum=int(random.random()*4)
                #加入一个body,设置好坐标,应该是加在上次腾出的地方
                snakebody=westiceSnakeBody()
                snakebody.x=self.westicesnake.prev_snakex
                snakebody.y=self.westicesnake.prev_snakey
                self.westicesnake.bodys.append(snakebody)
            #在land中随机产生蛋糕
            tempindex=int(random.random()*self.gridwidth*self.gridheight)
            if self.landsqurelist[tempindex].randnum==-1:
                randnum=int(random.random()*4)
                imagename='land'+str(randnum)+'.jpg'  
                self.landsqurelist[tempindex].randnum=randnum
            else:
                imagename='land-1.jpg'
                self.landsqurelist[tempindex].randnum=-1 
               
            img1=wx.Image(imagename,wx.BITMAP_TYPE_ANY)
            img1=img1.Scale(30,30)
            self.landsqurelist[tempindex].SetBitmap(wx.BitmapFromImage(img1))
        else:
            self.gamestatustxt.SetLabel('游戏状态:GameOver!')
            
        #移动小蛇
        self.westicesnake.update()    
    #得到图片的x,y坐标
    def getX_Y(self,imageindex):
        x=imageindex%self.gridwidth
        y=imageindex/self.gridwidth
        return [x,y]
    def getIndex(self,x,y):
        return y*self.gridwidth+x        
        
#代码入口
if __name__=='__main__':
    app=wx.PySimpleApp()
    frame=MyFrame()
    frame.Show(True)
    app.MainLoop()



 

你可能感兴趣的:(游戏,算法,wxPython)