3.4 render()方法
render()方法的作用是根据tankPos在游戏窗口中绘制坦克精灵,在绘制坦克精灵时,需要确定的数据是坦克精灵所在空格的左上角横纵坐标,以及绘制要绘制的贴图在贴图集中的位置,代码如图8所示。
图8 render()方法的代码
其中第69行代码中spritePoint即为坦克精灵所在空格的左上角横纵坐标,该变量的含义如图9所示。
图9 变量spritePoint的示意图
第70行中定义的变量texturePoint表示要绘制的贴图在贴图集中的位置,Vector2(1,0)表示贴图位于贴图集的第1行,第2列(Vector2的第一个参数表示列数,第二个参数表示行数,都是从0开始的),其示意图如图10所示。
图10 变量texturePoint的示意图
第71-72行定义的textureRect变量表示显示图10中绿框部分的内容,前两个参数表示绿框左上角的横纵坐标,后两个参数表示绿框的宽度和高度。
其它部分的代码与“矩形移动”游戏中的代码相同,请参考下一节的完整代码。
4 完整代码
“移动坦克”游戏的完整代码如下所示。
import os
import pygame
from pygame import Rect
from pygame.math import Vector2
class GameState():
def __init__(self):
self.worldSize = Vector2(16,10)
self.tankPos = Vector2(0,0)
def update(self,moveTankCommand):
self.tankPos += moveTankCommand
if self.tankPos.x < 0:
self.tankPos.x = 0
elif self.tankPos.x >= self.worldSize.x:
self.tankPos.x = self.worldSize.x - 1
if self.tankPos.y < 0:
self.tankPos.y = 0
elif self.tankPos.y >= self.worldSize.y:
self.tankPos.y = self.worldSize.y - 1
class UserInterface():
def __init__(self):
pygame.init()
self.gameState = GameState()
self.unitsTexture = pygame.image.load("units.png")
self.cellSize = Vector2(64,64)
windowSize = self.gameState.worldSize.elementwise() * self.cellSize
self.window = pygame.display.set_mode((int(windowSize.x),int(windowSize.y)))
pygame.display.set_caption("移动坦克")
self.moveTankCommand = Vector2(0,0)
self.clock = pygame.time.Clock()
self.running = True
def processInput(self):
self.moveTankCommand = Vector2(0,0)
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
break
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
self.running = False
break
elif event.key == pygame.K_RIGHT:
self.moveTankCommand.x = 1
elif event.key == pygame.K_LEFT:
self.moveTankCommand.x = -1
elif event.key == pygame.K_DOWN:
self.moveTankCommand.y = 1
elif event.key == pygame.K_UP:
self.moveTankCommand.y = -1
def update(self):
self.gameState.update(self.moveTankCommand)
def render(self):
self.window.fill((0,0,0))
spritePoint = self.gameState.tankPos.elementwise()*self.cellSize
texturePoint = Vector2(1,0).elementwise()*self.cellSize
textureRect = Rect(int(texturePoint.x), int(texturePoint.y),
int(self.cellSize.x),int(self.cellSize.y))
self.window.blit(self.unitsTexture,spritePoint,textureRect)
pygame.display.update()
def run(self):
while self.running:
self.processInput()
self.update()
self.render()
self.clock.tick(60)
userInterface = UserInterface()
userInterface.run()
pygame.quit()