很常见的游戏之一,实现原理并不复杂,并且参考了几个相关的代码。这边主要还是以学习编程语言和学习编程思路为重点记录一下吧。最近时间有点吃紧,只能匆忙记录一下。用pygame做的大鱼吃小鱼的游戏截图如下:(有些鱼的图片背景没有做透明处理,这块确实需要点美工时间,只能先凑合了)。

下面的图片是网上随便找的素材,这里用于切换主角的图片有三张,其他则是其他小鱼和boss鱼。我们控制的主人鱼的大小范围来决定加载不同的图片。以上准备的素材,其中一些背景色没有时间做处理,所以游戏中会有难看的背景色,只能凑合着用。。。

一、玩法及逻辑相关:

  控制你的鱼,有个初始大小,当碰到比你小的鱼的时候,你会吃掉它,并且会变大;遇到比你大的鱼,受到一点伤害,当总生命值为0时,失败游戏结束;当你控制的鱼大小增大最大时,游戏获胜。当鱼受到伤害时,有一段时间是无敌时间,且会闪烁。下面是主要的逻辑处理代码

  

        flashIsOn=round(time.time(),1)*10%2==1
if not gameOverMode and not (invulnerableMode and flashIsOn):
playerobj['rect']=pygame.Rect((playerobj['x']-camerax,playerobj['y']
-cameray,playerobj['size'],playerobj['size']))
SCREEN.blit(playerobj['surface'],playerobj['rect'])
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type==KEYDOWN:
if event.key in (K_UP,K_w):
moveDown =False
moveUp = True
elif event.key in (K_DOWN,K_s):
moveDown =True
moveUp = False
elif event.key in (K_LEFT,K_a):
moveRight = False
moveLeft= True
if playerobj['facing']==RIGHT:
playerobj['surface']=playersurfaceset(playerobj['size'], True)
playerobj['facing']=LEFT
elif event.key in (K_RIGHT,K_d):
moveRight = True
moveLeft= False
if playerobj['facing']==LEFT:
playerobj['surface']=playersurfaceset(playerobj['size'], False)
playerobj['facing']=RIGHT
elif winMode and event.key == K_r:
return
elif event.type==KEYUP:
if event.key in (K_LEFT,K_a):
moveLeft=False
elif event.key in (K_RIGHT,K_d):
moveRight=False
elif event.key in (K_UP,K_w):
moveRight=False
elif event.key in (K_DOWN,K_s):
moveRight=False
if not gameOverMode:
if moveLeft:
playerobj['x']-=MOVESPEED
if moveRight:
playerobj['x']+=MOVESPEED
if moveUp:
playerobj['y']-=MOVESPEED
if moveDown:
playerobj['y']+=MOVESPEED
for i in range(len(fishobjs)-1,-1,-1):
obj=fishobjs[i]
if 'rect' in obj and playerobj['rect'].colliderect(obj['rect']):
if obj['width']*obj['height']<=playerobj['size']**2:
playerobj['size']+=int((obj['width']*obj['height'])**0.2)
del fishobjs[i]
if playerobj['face']== LEFT:
playerobj['surface']=playersurfaceset(playerobj['size'],True)
if playerobj['face']== RIGHT:
playerobj['surface']=playersurfaceset(playerobj['size'],False)
if playerobj['size']>WINSIZE:
winMode=True
elif not invulnerableMode:
invulnerableMode=True
invulnerableStartTime=time.time()
playerobj['health']-=1
if playerobj['health']==0:
gameOverMode =True
gameOverStartTime=time.time()

主人公的控制类似一般的处理,这边用flashIsonl来生成时间差(偶数值时间为真)playersurfaceset()函数决定主人公的图片类型。

二、敌方鱼的生成处理

  上篇做的敌方的处理会在当前视口随即出现,这个突兀感太强,鱼的出现也不能随机显示在当前视口,应该由摄像机视角之外生成才符合常理。并且当鱼离摄像区域太远的距离,需要删除掉鱼对象。

 for i in range(len(fishobjs)-1,-1,-1):
if isOutsideArea(camerax,cameray,fishobjs[i]):
del fishobjs[i]
while len(fishobjs)<10:
fishobjs.append(makeNewfish(camerax,cameray))
 def makeNewfish(camerax,cameray):
sq={}
generalSize=random.randint(5,25)
multiplier = random.randint(1,3)
sq['width'] = (generalSize +random.randint(0,10))*multiplier
sq['height']= (generalSize +random.randint(0,10))*multiplier
sq['x'],sq['y']=getRandomoffCameraPos(camerax,cameray,sq['width'],sq['height'])
sq['movx'] = getRandomVelcocity()
sq['movy'] = getRandomVelcocity()
if sq['movx']<0:
sq['surface']=surfaceset(sq['width'],sq['height'],True)
else:
sq['surface']=surfaceset(sq['width'],sq['height'],False)
return sq

三、跟随视角的处理

    这个主要是跟随主人公视角的问题,计算出主人公的中心点距离摄像机中心点的距离,当距离偏大的时候,需要移动摄像机的位置,具体处理代码如下:

  

         playerCenterx=playerobj['x']+int(playerobj['size']/2)
playerCentery=playerobj['y']+int(playerobj['size']/2)
if (camerax+HALF_WINWIDTH)-playerCenterx>CAMERASLACK:
camerax=playerCenterx+CAMERASLACK-HALF_WINWIDTH
elif playerCenterx-(camerax+HALF_WINWIDTH)>CAMERASLACK:
camerax=playerCenterx-CAMERASLACK-HALF_WINWIDTH
if (cameray+HALF_WINHEIGHT)-playerCentery>CAMERASLACK:
cameray=playerCentery+CAMERASLACK-HALF_WINHEIGHT
elif playerCentery-(camerax+HALF_WINHEIGHT)>CAMERASLACK:
cameray=playerCentery-CAMERASLACK-HALF_WINHEIGHT

大部分应该介绍的应该就这些了,只能说游戏这块水比较深,只能浅尝辄止一番,python做游戏只能简单玩玩,这块不是他的优势。有人感兴趣的话可以研究它,推荐一本不错的书《Making games with python $ pygame》,哎 只能说有巨人的肩膀上站真好。

园友交流群:21735072  有兴趣请加入~欢迎来灌水~~~~ 注明:博客园

附全部源代码如下,比较粗陋,建议以书上源码学习为主:

import pygame,sys,time,random
from pygame.locals import *
WINWIDTH=640
WINHEIGHT=480
CAMERASLACK=70
lfish_img=[]
FISHSIZE=8
PLAYERSIZE=3
SCREEN=None
rfish_img=[]
lplayer_img=[]
rplayer_img=[]
backgroundimg=None
rboss_img=None
lboss_img=None
FPS=30
WHITE=[255,255,255]
MAXHEALTH=3
MINSPEED=3
MAXSPEED=9
MOVESPEED=7
HALF_WINWIDTH=int(WINWIDTH/2)
HALF_WINHEIGHT=int(WINHEIGHT/2)
WINSIZE=300
def main():
global FPSCLOCK,SCREEN,lfish_img,rfish_img,lplayer_img,rplayer_img,BASICFONT\
,rboss_img,lboss_img,backgroundimg
pygame.init()
FPSCLOCK=pygame.time.Clock()
SCREEN=pygame.display.set_mode((WINWIDTH,WINHEIGHT))
pygame.display.set_caption("fish eat fish")
BASICFONT=pygame.font.Font("freesansbold.ttf",32)
for i in range(FISHSIZE):
fishimg=pygame.image.load("Fish%s.bmp" % i)
fishimg.set_colorkey(WHITE)
lfish_img.append(fishimg)
rfishimg=pygame.transform.flip(fishimg,True,False) rfish_img.append(rfishimg)
for i in range(PLAYERSIZE):
playerimg=pygame.image.load("player%s.png" % i)
playerimg.set_colorkey(WHITE)
lplayer_img.append(playerimg)
rplayerimg=pygame.transform.flip(playerimg,True,False)
rplayerimg.set_colorkey(WHITE)
rplayer_img.append(rplayerimg)
bossimg=pygame.image.load("boss.png")
# bossimg.set_colorkey([0,0,0])
# SCREEN.blit(bossimg,(0,0))
lboss_img=bossimg
rbossimg=pygame.transform.flip(bossimg,True,False)
rboss_img=rbossimg backgroundimg=pygame.image.load("background.jpg") while True:
runGame()
def runGame():
invulnerableMode=False
invulnerableStartTime=0
gameOverMode=False
gameOverStartTime=0
winMode = False gameOverSurf=BASICFONT.render('Game Over',True,WHITE)
gameOverRect=gameOverSurf.get_rect()
gameOverRect.center=(HALF_WINWIDTH,HALF_WINHEIGHT) winSurf=BASICFONT.render('you succeed',True,WHITE)
winRect=winSurf.get_rect()
winRect.center=(HALF_WINWIDTH,HALF_WINHEIGHT) winSurf2=BASICFONT.render('you succeed',True,WHITE)
winRect2=winSurf2.get_rect()
winRect2.center=(HALF_WINWIDTH,HALF_WINHEIGHT+30) camerax=0
cameray=0
LEFT=0
RIGHT=1
fishobjs=[]
playerobj={'surface':pygame.transform.scale(lplayer_img[0],(25,25)),
'size':25,
'facing':LEFT,
'x':HALF_WINWIDTH,
'y':HALF_WINHEIGHT,
'health':MAXHEALTH}
moveLeft = False
moveRight = False
moveUp = False
moveDown = False while True:
if invulnerableMode and time.time() - invulnerableStartTime>2:
invulnerableMode =False
for sobj in fishobjs:
sobj['x']+=sobj['movx']
sobj['y']+=sobj['movy'] for i in range(len(fishobjs)-1,-1,-1):
if isOutsideArea(camerax,cameray,fishobjs[i]):
del fishobjs[i]
while len(fishobjs)<5:
fishobjs.append(makeNewfish(camerax,cameray))
playerCenterx=playerobj['x']+int(playerobj['size']/2)
playerCentery=playerobj['y']+int(playerobj['size']/2)
if (camerax+HALF_WINWIDTH)-playerCenterx>CAMERASLACK:
camerax=playerCenterx+CAMERASLACK-HALF_WINWIDTH
elif playerCenterx-(camerax+HALF_WINWIDTH)>CAMERASLACK:
camerax=playerCenterx-CAMERASLACK-HALF_WINWIDTH
if (cameray+HALF_WINHEIGHT)-playerCentery>CAMERASLACK:
cameray=playerCentery+CAMERASLACK-HALF_WINHEIGHT
elif playerCentery-(camerax+HALF_WINHEIGHT)>CAMERASLACK:
cameray=playerCentery-CAMERASLACK-HALF_WINHEIGHT
backrect=pygame.Rect((camerax-WINWIDTH,cameray-WINHEIGHT,WINWIDTH*3,WINHEIGHT*3))
newbackgroundimg=pygame.transform.scale(backgroundimg,(WINWIDTH*3,WINHEIGHT*3))
SCREEN.blit(newbackgroundimg,backrect) for obj in fishobjs:
obj['rect']=pygame.Rect((obj['x']-camerax,obj['y']-cameray,obj['width']
,obj['height']))
SCREEN.blit(obj['surface'],obj['rect']) flashIsOn=round(time.time(),1)*10%2==1
if not gameOverMode and not (invulnerableMode and flashIsOn):
playerobj['rect']=pygame.Rect((playerobj['x']-camerax,playerobj['y']
-cameray,playerobj['size'],playerobj['size']))
SCREEN.blit(playerobj['surface'],playerobj['rect'])
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type==KEYDOWN:
if event.key in (K_UP,K_w):
moveDown =False
moveUp = True
elif event.key in (K_DOWN,K_s):
moveDown =True
moveUp = False
elif event.key in (K_LEFT,K_a):
moveRight = False
moveLeft= True
if playerobj['facing']==RIGHT:
playerobj['surface']=playersurfaceset(playerobj['size'], True)
playerobj['facing']=LEFT
elif event.key in (K_RIGHT,K_d):
moveRight = True
moveLeft= False
if playerobj['facing']==LEFT:
playerobj['surface']=playersurfaceset(playerobj['size'], False)
playerobj['facing']=RIGHT
elif winMode and event.key == K_r:
return
elif event.type==KEYUP:
if event.key in (K_LEFT,K_a):
moveLeft=False
elif event.key in (K_RIGHT,K_d):
moveRight=False
elif event.key in (K_UP,K_w):
moveRight=False
elif event.key in (K_DOWN,K_s):
moveRight=False
if not gameOverMode:
if moveLeft:
playerobj['x']-=MOVESPEED
if moveRight:
playerobj['x']+=MOVESPEED
if moveUp:
playerobj['y']-=MOVESPEED
if moveDown:
playerobj['y']+=MOVESPEED
for i in range(len(fishobjs)-1,-1,-1):
obj=fishobjs[i]
if 'rect' in obj and playerobj['rect'].colliderect(obj['rect']):
if obj['width']*obj['height']<=playerobj['size']**2:
playerobj['size']+=int((obj['width']*obj['height'])**0.2)
del fishobjs[i]
if playerobj['face']== LEFT:
playerobj['surface']=playersurfaceset(playerobj['size'],True)
if playerobj['face']== RIGHT:
playerobj['surface']=playersurfaceset(playerobj['size'],False)
if playerobj['size']>WINSIZE:
winMode=True
elif not invulnerableMode:
invulnerableMode=True
invulnerableStartTime=time.time()
playerobj['health']-=1
if playerobj['health']==0:
gameOverMode =True
gameOverStartTime=time.time()
if winMode:
SCREEN.blit(winSurf,winRect)
SCREEN.blit(winSurf2,winRect2)
pygame.display.update()
FPSCLOCK.tick(FPS)
def isOutsideArea(camerax,cameray,fishobj):
boundsLeftEdge =camerax-WINWIDTH
boundsTopEdge=cameray-WINHEIGHT
boundsRect=pygame.Rect(boundsLeftEdge,boundsTopEdge,WINWIDTH*3,WINHEIGHT*3)
objRect=pygame.Rect(fishobj['x'],fishobj['y'],fishobj['width'],fishobj['height'])
return not boundsRect.colliderect(objRect)
def makeNewfish(camerax,cameray):
sq={}
generalSize=random.randint(5,25)
multiplier = random.randint(1,3)
sq['width'] = (generalSize +random.randint(0,10))*multiplier
sq['height']= (generalSize +random.randint(0,10))*multiplier
sq['x'],sq['y']=getRandomoffCameraPos(camerax,cameray,sq['width'],sq['height'])
sq['movx'] = getRandomVelcocity()
sq['movy'] = getRandomVelcocity()
if sq['movx']<0:
sq['surface']=surfaceset(sq['width'],sq['height'],True)
else:
sq['surface']=surfaceset(sq['width'],sq['height'],False)
return sq
def playersurfaceset(size,Face):
surface=None
if size<100:
if Face ==True:
surface= pygame.transform.scale(lplayer_img[0],(size,size))
else:
surface= pygame.transform.scale(rplayer_img[0],(size,size))
elif size<200 and size>=100:
if Face ==True:
surface= pygame.transform.scale(lplayer_img[1],(size,size))
else:
surface= pygame.transform.scale(rplayer_img[1],(size,size))
else:
if Face ==True:
surface= pygame.transform.scale(lplayer_img[2],(size,size))
else:
surface= pygame.transform.scale(rplayer_img[2],(size,size))
return surface
def surfaceset(width,height,Face):
surface=None
if width*height>200*200:
if Face == True:
surface= pygame.transform.scale(lboss_img,(width,height))
else:
surface= pygame.transform.scale(rboss_img,(width,height))
else:
index= int((width*height)%(FISHSIZE-1))
if Face == True:
surface= pygame.transform.scale(lfish_img[index],(width,height))
else:
surface= pygame.transform.scale(rfish_img[index],(width,height))
return surface
def getRandomVelcocity():
speed=random.randint(MINSPEED,MAXSPEED)
if random.randint(0,1):
return speed
else:
return -speed def getRandomoffCameraPos(camerax,cameray,objwidth,objheight):
cameraRect=pygame.Rect(camerax,cameray,WINWIDTH,WINHEIGHT)
while True:
x=random.randint(camerax-WINWIDTH,camerax+2*(WINWIDTH))
y=random.randint(camerax-WINHEIGHT,camerax+2*(WINHEIGHT))
objrect=pygame.Rect(x,y,objwidth,objheight)
if not objrect.colliderect(cameraRect):
return x,y
if __name__ == '__main__':
main()

ps:最近越来越懒了,不知道当初订的每周至少写一篇随笔的目标能否坚持下去。另外鄙视下12306上刷票的黄牛,刷了一天没买到票,哎 不说了都是泪。

写简单游戏,学编程语言-python篇:大鱼吃小鱼的更多相关文章

  1. 写简单游戏,学编程语言-python篇

    好吧, 首先得承认这个题目写的夸大了,人才菜鸟一枚,游戏相关编程也是知道点概念.但是本人对游戏开发比较感兴趣,相信大多数喜欢玩玩游戏,因为它给人确实带来很多乐趣,而编程语言的学习最少对于我来说比较乏味 ...

  2. 写简单游戏,学编程语言-python篇:传说哥大战剧毒术士

    上篇写的动画示例其实算不上一个游戏,顶多算是利用pygame进行的图形操作,今天着手实现一个小游戏:传说哥大战剧毒术士.名字很玄乎,其实就是最简单的一个射击游戏.好了废话不多说,先上截图吧: 一.初始 ...

  3. 56岁潘石屹生日当天宣布要学编程语言Python,网友:地产商来抢码农饭碗了!

    最近在码农界里,一个比较轰动的事情,就是地产大佬潘石屹,在56岁生日当天宣布要学习编程语言Python. 可能部分老铁不认识潘石屹,简单介绍下大佬背景: 潘石屹,1963年11月14日出生于甘肃天水, ...

  4. 功能强大而又简单易学的编程语言Python

    Python是一种面向对象.直译式计算机程序设计语言,也是一种功能强大的通用型语言.首先,Python非常简单,以Hello World为例: Java的Hello World程序一般这么写: pub ...

  5. 闲扯游戏编程之html5篇--山寨版《flappy bird》源码

    新年新气象,最近事情不多,继续闲暇学习记点随笔,欢迎拍砖.之前的〈简单游戏学编程语言python篇〉写的比较幼稚和粗糙,且告一段落.开启新的一篇关于javascript+html5的从零开始的学习.仍 ...

  6. 通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数--菜单功能'menufile

      通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁 ...

  7. 通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数

    通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账 ...

  8. 通过游戏学python 3.6 第一季 第二章 实例项目 猜数字游戏--核心代码--猜测次数 可复制直接使用 娱乐 可封装 函数

      猜数字游戏--核心代码--猜测次数   #猜数字--核心代码--猜测次数 number=33 amount=3 count=0 while count<=amount: conversion ...

  9. 人工智能时代,是时候学点Python了!

    “是时候学点Python了”.作为一名不怎么安分的程序员,你或许觉得,产生这样的想法并不奇怪,但学习Python却是出于自己对工作现状以及如何应对未来挑战所作出的思考.读过我以前博客的朋友,可能都知道 ...

随机推荐

  1. JavaScript中的splice方法

    splice方法根据传入的不同参数可分别实现删除和插入操作 使用splice(pra1,pra2,pra3)方法,需要为其提供如下参数: 1.pra1为其起始索引(即希望开始添加元素的地方) 2.pr ...

  2. IE10、IE11和Microsoft Edge的Hack

    IE10.IE11和Microsoft Edge的Hack 随着Win10的推广,Microsoft Edge浏览器已经越来越普遍,但是IE11也是伴随其中,尾大不掉. 首先,了解一下概念,如下图:微 ...

  3. BZOJ2408 混乱的置换

    这道题即THUSC 2015 t3...只不过数据范围$n, m ≤ 10^5$ 可以上网查这个鬼畜的东西"Burrows-Wheeler Transform" 这道题要用到解压缩 ...

  4. Oracle连接数据库的封装类OracleDB

    import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.S ...

  5. Game02 最新版本2.0.0

    Game02发布转站于此,欢迎大家下载.... 简介: Game02是由ImGenius开发的一款即时在线小游戏.玩法简单,易于上手,主要靠技术,不会出现不要脸的充值等内容. 操控方法:W和A左右移动 ...

  6. daydayup2 codeforces143D

    这题很考察分析 题意:让你构造n*m的矩阵,使得不存在两个点的距离的平方为5 1若n=1  ,答案为m 2若m=1,答案为n 3若n=2 则这样 110011001100.. 110011001100 ...

  7. 关于WPF程序启动性能

    项目里WPF的启动时间太久(>1分钟),显然是不能接受的.超过10秒,连Loading的等待框都会让用户感到厌烦. 1. 症状 项目的结构是1个WPF主进程,启动3个WPF子进程.子进程在启动时 ...

  8. 安卓自动化测试:Android studio 自带的 Record Espresso Test || [ Appium & (Android studio || Python|| Eclipse ) ]

    1.Android studio 自带的 Record Espresso Test  https://developer.android.com/studio/test/espresso-test-r ...

  9. UITableViewCell里面separator的设置

    最近cell显示的时候左边一直有15个像素的偏移,查了下面的方法 //1. 不管用 [self.tableView setSeparatorInset:UIEdgeInsetsZero]; // 2. ...

  10. php 数据库insert函数

    <?php function into($constr) { $con = mysql_connect("localhost","root"," ...