赞
踩
通过一顿的代码分析后,我发现是i和j
计算公式对调了,因为x
其实代表的才是游戏元素的起始left
位置,y
代表的才是游戏元素的起始top
位置。所以正确代码应该是:
j = (x-20)//50 #20为游戏元素起始top位置,50为游戏元素长度
i = (y-20)//50#20为游戏元素起始left位置,50为游戏元素宽度
完整正确代码:
import pygame import sys import time import random from MagicBlock import Block SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 if __name__ == '__main__': pygame.init() screen = pygame.display.set_mode((SCREEN_HEIGHT,SCREEN_WIDTH)) pygame.display.set_caption("happy remove") screen.fill((124,114,242)) blocks=[[0]*8 for i in range(8)] for i in range(8): for j in range(8): #位置的计算公式为left = 起始left位置+元素宽度*j,top=起始top位置+元素高度*i blocks[i][j] = Block(screen,20+50*j,20+50*i,50,50,(random.randint(0,255),random.randint(0,255),random.randint(0,255))) blocks[i][j].draw() #更新窗口 pygame.display.update() while True: #获取鼠标响应 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0) elif event.type ==pygame.MOUSEBUTTONDOWN: x,y = event.pos j = (x-20)//50 #20为游戏元素起始top位置,50为游戏元素长度 i = (y-20)//50#20为游戏元素起始left位置,50为游戏元素宽度 blocks[i][j].color = (124,114,242) blocks[i][j].draw() pygame.display.update() time.sleep(0.3)
在上篇文章中,我们实现了点击消除游戏元素事件,由于矩形元素有点太丑陋了,所以我们将矩形元素替换成图像元素会好看点(说白了这章就是美化用的哈哈哈哈哈哈)
在pygame
中我们可以使用screen.blit(source,dest)
函数来绘制图像。
其中参数source
是某矩形图像(Surface实例),将被绘制到另一矩形图像screen(Surface实例)上由参数dest
指定位置。参数dest
是矩形图像source
左上角在screen上的坐标。
为了获得Surface实例,我们可以通过pygame.image.load(图片路径)
加载图片,获取Surface实例。在这里我找了五张和消消乐相关的图片作为游戏元素,想要的可以私聊我找我要。
我们在原有的代码基础上添加如下代码进行测试:
screen.blit(pygame.image.load('./image/01_hightlight.png'),(20,450))
完整代码如下:
import pygame import sys import time import random from MagicBlock import Block SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 if __name__ == '__main__': pygame.init() screen = pygame.display.set_mode((SCREEN_HEIGHT,SCREEN_WIDTH)) pygame.display.set_caption("happy remove") screen.fill((124,114,242)) blocks=[[0]*8 for i in range(8)] for i in range(8): for j in range(8): #位置的计算公式为left = 起始left位置+元素宽度*j,top=起始top位置+元素高度*i blocks[i][j] = Block(screen,20+50*j,20+50*i,50,50,(random.randint(0,255),random.randint(0,255),random.randint(0,255))) blocks[i][j].draw() screen.blit(pygame.image.load('./image/01_hightlight.png'),(20,450)) #更新窗口 pygame.display.update() while True: #获取鼠标响应 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0) elif event.type ==pygame.MOUSEBUTTONDOWN: x,y = event.pos j = (x-20)//50 #20为游戏元素起始top位置,50为游戏元素长度 i = (y-20)//50#20为游戏元素起始left位置,50为游戏元素宽度 blocks[i][j].color = (124,114,242) blocks[i][j].draw() pygame.display.update() time.sleep(0.3)
效果图如下:
我们可以看到在全部元素下方显示了小熊的图像。
我们想要Block
类既能绘制矩形元素,又能绘制图像元素,我们可以给Block
类添加type
属性,在绘制中判断该Block
实例是矩形元素还是图像元素。
由于不同的元素,所需要的属性是不同的(比如矩形元素需要颜色信息,图像元素需要图像),所以我们可以通过将image和color设置默认为None
,在需要的时候进行赋值即可。
代码如下:
-MagicBlock.py
import pygame
class Block:
def __init__(self,screen,left,top,width,height,type,image=None,color=None):
self.screen = screen
self.left = left
self.top = top
self.type = type
self.image = image
self.color = color
self.width = width
self.height = height
def draw(self):
position = self.left,self.top,self.width,self.height
pygame.draw.rect(self.screen,self.color,position)
上述代码仅只是将属性进行添加,类的行为也要改变,我们可以通过if
判断类型来实现不同元素的绘制。同时我们可以给Block设置全局变量来判断是那种类型,具体代码如下:
-MagicBlock.py import pygame TYPE_RECT = 0 TYPE_IMAGE = 1 class Block: def __init__(self,screen,left,top,width,height,type,image=None,color=None): self.screen = screen self.left = left self.top = top self.type = type self.image = image self.color = color self.width = width self.height = height def draw(self): if self.type == TYPE_RECT: position = self.left,self.top,self.width,self.height pygame.draw.rect(self.screen,self.color,position) elif self.type == TYPE_IMAGE: self.screen.blit(self.image,(self.left,self.top))
同时我们也要更改主入口文件中调用类的接口,由于我们的image文件名呢是根据0i{1-5}_hightlight.png
来命名,所以我们可以通过random.randint(1,5)
来动态变更每个位置的图像。更改代码如下:
import MagicBlock
Block(screen,20+50*j,20+50*i,50,50,MagicBlock.TYPE_IMAGE,image=pygame.image.load('./image/0'+str(random.randint(1,5))+"_hightlight.png"))
完整代码如下:
-main.py import pygame import sys import time import random from MagicBlock import Block import MagicBlock SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 if __name__ == '__main__': pygame.init() screen = pygame.display.set_mode((SCREEN_HEIGHT,SCREEN_WIDTH)) pygame.display.set_caption("happy remove") screen.fill((124,114,242)) blocks=[[0]*8 for i in range(8)] for i in range(8): for j in range(8): #位置的计算公式为left = 起始left位置+元素宽度*j,top=起始top位置+元素高度*i blocks[i][j] = Block(screen,20+50*j,20+50*i,50,50,MagicBlock.TYPE_IMAGE,image=pygame.image.load('./image/0'+str(random.randint(1,5))+"_hightlight.png")) blocks[i][j].draw() #更新窗口 pygame.display.update() while True: #获取鼠标响应 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0) elif event.type ==pygame.MOUSEBUTTONDOWN: x,y = event.pos j = (x-20)//50 #20为游戏元素起始top位置,50为游戏元素长度 i = (y-20)//50#20为游戏元素起始left位置,50为游戏元素宽度 blocks[i][j].color = (124,114,242) blocks[i][j].draw() pygame.display.update() time.sleep(0.3)
效果图如下:
本篇文章美化了游戏元素,但是深入分析我们发现点击消除事件失效,以及对于每一个元素消除都需要在主函数中独立操作,且我们看到随着后续内容的增加,main.py
会越来越臃肿,我们想着能否再用一个类来将矩阵游戏元素作为整体来操作,我们只需要在主函数中操作该类需要执行的动作即可,这样不仅架构清晰,而且操作方便,也就不需要再主函数中不断修改了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。