pygame学习----一个鼠标游戏

2014-11-24 03:13:53 · 作者: · 浏览: 0

之前玩了一个经典的鼠标游戏,觉得十分有趣(玩得简直想砸电脑),于是有了仿制一个的想法。一直拖啊拖啊拖,今天终于实现,不容易啊哭

这个也只算是半成品,因为障碍物目前只做了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]])