用户:天上的流星_tianqiVirus查看:1 回复:3 评论:1 创建时间:2019-12-29T13:34:29
教你用pygame开发游戏
今日游戏:喵大战(自创)
如果对几行代码没有看懂,那么你可能是没看过上一次的帖子
那就去看看我之前的帖子
前几周我的电脑碎了,现在终于弄好过来
为了庆祝,我决定开发一个游戏
我们先来弄点图片
暂时就这两张,分别命名为myTank.png和enemyTank.png
保存于py文件所属文件夹下assests/image文件夹
然后就是写代码了
做成大概这个样子
如果你看不懂代码,请参考我以前的帖子
import pygame
width = 720
height = 540
fps = 32
title = 'tank war'
pygame.init()
screen = pygame.display.set_mode([width,height])
pygame.display.set_caption(title)
timer = pygame.time.Clock()
keepGoing = True
doingTime = 0
while keepGoing:
doingTime+=1
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
pygame.display.update()
timer.tick(32)
exit()
这里我先讲一下一些代码
pygame.display.set_caption()是设置标题
使用doingTime变量是为了方便在主循环中计数
然后准备图片文件
ok
下一步,我们开始面向对象的编程
在主循环钱编写玩家喵的代码
先搭基本框架
class player:
def __init__(self,x,y,image):
pass
def playerUpdate(self,screen):
pass
在此,我们喵家显示和更新的代码放在一个方法里
然后,我们进行初始化玩家的操作
def __init__(self,x,y,image):
self.x = x
self.y = y
self.speed = 3
self.image = image
self.rect = pygame.Rect(self.x+4,self.y+12,10,12)
在这里我要指出,可以使用get_rect()的方法创建rect对象,但是这样会导致把过多的空余部分算进去
所以我还是用普通的pygame.Rect创建
然后我们编写玩家更新的代码
def playerUpdate(self,screen):
self.rect = pygame.Rect(self.x+4,self.y+12,10,12)
screen.blit(self.image,(self.x,self.y))
请注意,这里的screen和上面的screen = pygame.display.set_mode()的screen不一样
前者是playerUpdate传入的参数
好的,现在我们来看看效果
请修改部分代码
其效果为
很显然,这个太小了
我们用transform来调整大小
我以前的帖子里说的是pygame.transform.喵oothscale(),但是这个在低分辨率图片中效果不好
所以我们改用pygame.transform.scale()
我们图片的大小是18*27,长宽比为2:3,不妨改为22*33
tankImages = [pygame.transform.scale(pygame.image.load("assets/image/myTank.png"),(22,33)),pygame.transform.scale(pygame.image.load("assets/image/enemyTank.png"),(22,33))]
代码如图所示
请注意,改变图片大小后会导致角色矩形与图片不符,所以我们也要改变rect
大概这么大
运行后,可以发现大小大了一点,但至少比以前要好
至于为什么不用更大的大小,我们以后的帖子会提到
接下来我们加上移动喵的代码
喵移动是靠键盘上下左右键操控的,所以我们先在循环中加入
while keepGoing:
doingTime+=1
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
pass
if event.key == pygame.K_RIGHT:
pass
if event.key == pygame.K_UP:
pass
if event.key == pygame.K_DOWN:
pass
myTank.playerUpdate(screen)
pygame.display.update()
timer.tick(32)
exit()
这四个键代表不同方向的移动
不同方向的移动需要喵图片不同的朝向
在此,我们用pygame.transform.rotate()来改变朝向
这个方法需要两个参数,图片和角度
不过在此之前,我们需要一个变量表示方向,以及一个旋转的原料
def __init__(self,x,y,image):
self.x = x
self.y = y
self.speed = 3
self.image = image
self.tankImage = image
self.facing = 0
self.rect = pygame.Rect(self.x+5,self.y+14,12,14)
即上图中的tankImage和facing
这里的旋转机制有点复杂,代码如下
class player:
def __init__(self,x,y,image):
self.x = x
self.y = y
self.speed = 3
self.image = image
self.tankImage = image
self.facing = 0
self.rect = pygame.Rect(self.x+5,self.y+14,12,14)
def playerUpdate(self,screen):
if self.facing == 0:
self.rect = pygame.Rect(self.x+5,self.y+14,12,14)
elif self.facing == 1:
self.rect = pygame.Rect(self.x+3,self.y+5,14,12)
elif self.facing == 2:
self.rect = pygame.Rect(self.x+5,self.y+3,12,14)
elif self.facing == 3:
self.rect = pygame.Rect(self.x+14,self.y+5,14,12)
self.image = pygame.transform.rotate(self.tankImage,self.facing*90)
screen.blit(self.image,(self.x,self.y))
myTank = player(100,200,tankImages[0])
while keepGoing:
doingTime+=1
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
myTank.facing = 1
myTank.x-=7
if event.key == pygame.K_RIGHT:
myTank.facing = 3
myTank.x+=7
if event.key == pygame.K_UP:
myTank.facing = 0
myTank.y-=7
if event.key == pygame.K_DOWN:
myTank.facing = 2
myTank.y+=7
myTank.playerUpdate(screen)
pygame.display.update()
timer.tick(32)
exit()
主要思想是旋转过后坐标,大小,矩形都要改变,具体变化数值请参考如上代码
然后我们的设定是按键盘控制方向,按ws控制移动,按空格控制开炮
开炮的代码现在不弄,控制键盘的代码已经弄好了,所以我们做ws控制移动的代码
这就需要控制坐标移动的变量,即xChange,yChange
也要记得每次更新改变坐标
代码如下
class player:
def __init__(self,x,y,image):
self.x = x
self.y = y
self.speed = 3
self.image = image
self.tankImage = image
self.facing = 0
self.xChange = 0
self.yChange = 0
self.rect = pygame.Rect(self.x+5,self.y+14,12,14)
def playerUpdate(self,screen):
self.x+=self.xChange
self.y+=self.yChange
if self.facing == 0:
self.rect = pygame.Rect(self.x+5,self.y+14,12,14)
elif self.facing == 1:
self.rect = pygame.Rect(self.x+3,self.y+5,14,12)
elif self.facing == 2:
self.rect = pygame.Rect(self.x+5,self.y+3,12,14)
elif self.facing == 3:
self.rect = pygame.Rect(self.x+14,self.y+5,14,12)
self.image = pygame.transform.rotate(self.tankImage,self.facing*90)
screen.blit(self.image,(self.x,self.y))
然后是判断ws键的代码
此时,我们只需要改变xChange,yChange即可
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
myTank.facing = 1
myTank.x-=7
if event.key == pygame.K_RIGHT:
myTank.facing = 3
myTank.x+=7
if event.key == pygame.K_UP:
myTank.facing = 0
myTank.y-=7
if event.key == pygame.K_DOWN:
myTank.facing = 2
myTank.y+=7
if event.key == pygame.K_w or event.key == pygame.K_s:
myTank.xChange = 0
myTank.yChange = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
myTank.xChange=[0,myTank.speed,0,-myTank.speed][myTank.facing]
myTank.yChange=[-myTank.speed,0,myTank.speed,0][myTank.facing]
if event.key == pygame.K_s:
myTank.xChange=[0,-myTank.speed,0,myTank.speed][myTank.facing]
myTank.yChange=[myTank.speed,0,-myTank.speed,0][myTank.facing]
同时为了调试方便,我们暂时在每次循环中给屏幕加上背景
这样,我们这次的任务就完成了
最终代码为
import pygame
width = 720
height = 540
fps = 32
title = 'tank war'
pygame.init()
screen = pygame.display.set_mode([width,height])
pygame.display.set_caption(title)
timer = pygame.time.Clock()
tankImages = [pygame.transform.scale(pygame.image.load("assets/image/myTank.png"),(22,33)),pygame.transform.scale(pygame.image.load("assets/image/enemyTank.png"),(22,33))]
keepGoing = True
doingTime = 0
class player:
def __init__(self,x,y,image):
self.x = x
self.y = y
self.speed = 3
self.image = image
self.tankImage = image
self.facing = 0
self.xChange = 0
self.yChange = 0
self.rect = pygame.Rect(self.x+5,self.y+14,12,14)
def playerUpdate(self,screen):
self.x+=self.xChange
self.y+=self.yChange
if self.facing == 0:
self.rect = pygame.Rect(self.x+5,self.y+14,12,14)
elif self.facing == 1:
self.rect = pygame.Rect(self.x+3,self.y+5,14,12)
elif self.facing == 2:
self.rect = pygame.Rect(self.x+5,self.y+3,12,14)
elif self.facing == 3:
self.rect = pygame.Rect(self.x+14,self.y+5,14,12)
self.image = pygame.transform.rotate(self.tankImage,self.facing*90)
screen.blit(self.image,(self.x,self.y))
myTank = player(100,200,tankImages[0])
while keepGoing:
doingTime+=1
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
myTank.facing = 1
myTank.x-=7
if event.key == pygame.K_RIGHT:
myTank.facing = 3
myTank.x+=7
if event.key == pygame.K_UP:
myTank.facing = 0
myTank.y-=7
if event.key == pygame.K_DOWN:
myTank.facing = 2
myTank.y+=7
if event.key == pygame.K_w or event.key == pygame.K_s:
myTank.xChange = 0
myTank.yChange = 0
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
myTank.xChange=[0,myTank.speed,0,-myTank.speed][myTank.facing]
myTank.yChange=[-myTank.speed,0,myTank.speed,0][myTank.facing]
if event.key == pygame.K_s:
myTank.xChange=[0,-myTank.speed,0,myTank.speed][myTank.facing]
myTank.yChange=[myTank.speed,0,-myTank.speed,0][myTank.facing]
myTank.playerUpdate(screen)
pygame.display.update()
timer.tick(32)
exit()
想要继续学习pygame和游戏制作的请关注
id:小鹿工作室_天上的流星
本帖内的所有代码,思想仅供参考,请勿用于盈利用途