之前玩了一个经典的鼠标游戏,觉得十分有趣(玩得简直想砸电脑),于是有了仿制一个的想法。一直拖啊拖啊拖,今天终于实现,不容易啊
这个也只算是半成品,因为障碍物目前只做了3种(两种静止的,一种平移的),关卡数也只做了2关,只有日后有时间再补充完善了!
截图是这样:
vcLMteO0pqGjPC9wPgo8cD48L3A+CjxwPrLZ1/ejujwvcD4KPHA+sLTPwsrzserSxravuuy146Oss6SwtLrsteO+zdK71rG4+tfFyvOx6tLGtq+jrLWry9m2yLK7u+GzrLn9c3BlZWQmIzIwNTQwO6O7sLRFc2O8/Lvy09LJz83Ls/bTzs+3o7uwtL/VJiMyNjY4NDvWsb3TvfjI68/C0ru52KGjPC9wPgo8YnI+CjxwPtLGtq+67LXjyrnTw7W9wctnYW1lb2JqZWN0c8Sjv+mjrNXiysfSu7j2tdrI/be9xKO/6aOsv8nS1NTaIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvZ2FtZW9iamVjdHMvICAgz8LU2DwvcD4KPHA+1/a3qMrHvMbL47rstePUstDEtb3K87HqzrvWw7XEz/LBv6OsyLu6872rz/LBv7XExKO6zcnotqi1xHNwZWVkJiMyMDU0MDuxyL3Po6zI57n7IA=="向量| < speed,就是说移动距离小于speed,直接将红点移动到鼠标位置;否则,按向量的方向移动speed距离。
至于碰撞检测,圆形和圆形比较简单,勾股定理就搞定了。圆形和矩形的检测稍微比前者麻烦点,分两种情况考虑,详见代码,还是很好理解的。
在maps文件夹里保存了地图的数据,
目前block块有三种(我程序里面规定了,编号数为偶数的代表矩形,基数代表圆形):
编号0的代表静止的矩形;
编号1代表静止的圆形;
编号2代表平移的矩形,list倒数第三个元素表示移动向量,最后两个元素表示终点和起点坐标,当当前位置等于终点坐标时,终点 起点坐标交换,移动向量取反就能实现反向运动了。
import pygame
from pygame.locals import *
import sys
from gameobjects.vector2 import Vector2
pygame.init()
size = width, height = 800, 600
screen = pygame.display.set_mode(size)
fps = pygame.time.Clock()
wallWidth = 20
font = pygame.font.Font('fonts/UbuntuMono-B.ttf', 26)
pygame.display.set_caption('A funny mouse game')
background = (255, 255, 255)
class Game:
def __init__(self):
self.blocks = []
self.starting = []
self.speed = 0
self.target = []
self.death = 0
self.totalDeath = 0
self.round = 0
def loadMap(self, fileName):
try:
mapFile = open(fileName, 'rU')
exec(mapFile.read())
mapFile.close()
return True
except:
print 'Load Map Error!!'
return False
def isWin(self):
d2 = (self.starting[0][0] - self.target[0][0]) ** 2 + (self.starting[0][1] - self.target[0][1]) ** 2
if (self.starting[1] + self.target[1]) ** 2 >= d2: return True
return False
def isLose(self):
sx, sy= self.starting[0]
rad = self.starting[1]
for block in self.blocks:
if block[0] & 1:
x, y = block[1]
r= block[2]
if (sx - x) ** 2 + (sy - y) ** 2 <= (rad + r) ** 2: return True
else:
x, y, w, h = block[1]
if x <= sx <= x + w:
dis = min(abs(sy - y), abs(sy - (y + h)))
if dis <= self.starting[1]: return True
elif y <= sy <= y + h:
dis = min(abs(sx - x), abs(sx - (x + w)))
if dis <= self.starting[1]: return True
else:
if sx > x + w: x += w
if sy > y + h: y += h
if (sx - x) ** 2 + (sy - y) ** 2 <= rad ** 2:
return True
return False
def movePlayer(self):
mx, my = pygame.mouse.get_pos()
destination = Vector2(mx, my) - Vector2(self.starting[0])
magnitude = destination.get_magnitude()
if magnitude < self.speed:
self.starting[0] = mx, my
else:
self.starting[0] = Vector2(game.starting[0]) + destination.normalize() * self.speed
def draw(self):
#draw starting and target point
pygame.draw.circle(screen, self.starting[2], (int(self.starting[0][0]), int(self.starting[0][1])), self.starting[1])
pygame.draw.circle(screen, self.target[2], self.target[0], self.target[1])
#draw blocks
for block in self.blocks:
if block[0] & 1:
pygame.draw.circle(screen, block[3], block[1], block[2])
else:
pygame.draw.rect(screen, block[2], block[1])
#print info
screen.blit(font.render('Round: ' + str(self.round), True, (0, 0, 0)), (50, height - 35))
screen.blit(font.render('Death: ' + str(self.death), True, (255, 255, 0)), (330, height - 35))
screen.blit(font.render('Total Death: ' + str(self.totalDeath), True, (255, 0, 0)), (580, height - 35))
def move(self):
for block in self.blocks:
if block[0] == 2:
block[1][0] += block[3][0]
block[1][1] += block[3][1]
if [block[1][0], block[1][1]] == block[4]:
block[4], block[5] = block[5], block[4]
block[3][0], block[3][1] = -block[3][0], -block[3][1]
#---------------------------------------------------------------------#
game = Game()
level = 1
while level:
isNext = False
mb = 0
if not game.loadMap('maps/map' + str(level) + '.txt'): break
#add wall
game.blocks.append([0, (0, 0, 800, wallWidth), (0, 0, 255)])
game.blocks.append([0, (0, 0, wallWidth, 600), (0, 0, 255)])
game.blocks.append([0, (width - wallWidth, 0, wallWidth, 600), (0, 0, 255)])
game.blocks.append([0, (0, height - wallWidth - 30, 800, wallWidth + 30), (0, 0, 255)])
while 1:
fps.tick(100)
screen.fill(background)
game.draw()
pygame.display.update()
for evnt in pygame.event.get():
if evnt.type == QUIT or (evnt.type == KEYDOWN and evnt.key == K_ESCAPE):
pygame.quit()
exit()
elif evnt.type == KEYDOWN:
if evnt.key == K_SPACE:
isNext = True
elif evnt.type == MOUSEBUTTONDOWN:
if evnt.button == 1: mb = 1
elif evnt.type == MOUSEBUTTONUP:
if evnt.button == 1: mb = 0
game.move()
if mb == 1: game.movePlayer()
if game.isWin() or isNext:
level += 1
game.death = 0
break
if game.isLose():
game.death += 1
game.totalDeath += 1
break
pygame.quit()
exit()
第二关地图的代码:
#pos, radius, color self.starting = [[40, 300], 10, (255, 0, 0)] self.speed = 10 self.target = [[750, 300], 15, (0, 255, 0)] #round info self.round = 2 #blocks self.blocks = [] self.blocks.append([2, [100, 20, 50, 50],(0, 0, 0), [0, 8],[100, 500], [100, 20]]) self.blocks.append([2, [150, 500, 50, 50],(0, 0, 0), [0, -8],[150, 20], [150, 500]]) self.blocks.append([2, [200, 20, 50, 50],(0, 0, 0), [0, 8],[200, 500], [200, 20]]) self.blocks.append([2, [250, 500, 50, 50],(0, 0, 0), [0, -8],[250, 20], [250, 500]]) self.blocks.append([2, [300, 20, 50, 50],(0, 0, 0), [0, 8],[300, 500], [300, 20]]) self.blocks.append([2, [350, 500, 50, 50],(0, 0, 0), [0, -8],[350, 20], [350, 500]]) self.blocks.append([2, [400, 20, 50, 50],(0, 0, 0), [0, 8],[400, 500], [400, 20]]) self.blocks.append([2, [450, 500, 50, 50],(0, 0, 0), [0, -8],[450, 20], [450, 500]]) self.blocks.append([2, [500, 20, 50, 50],(0, 0, 0), [0, 8],[500, 500], [500, 20]]) self.blocks.append([2, [550, 500, 50, 50],(0, 0, 0), [0, -8],[550, 20], [550, 500]]) self.blocks.append([2, [600, 20, 50, 50],(0, 0, 0), [0, 8],[600, 500], [600, 20]]) self.blocks.append([2, [650, 500, 50, 50],(0, 0, 0), [0, -8],[650, 20], [650, 500]])