南昌大学百年校庆游戏彩球传说开源项目

本文仅基于项目需要开源,游戏基于之前写的Rapid_Roll的小游戏规则,仅以此致敬南昌大学百年校庆和按键机时代的经典游戏Rapid_Roll

先看实现效果
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

游戏说明:

	Rapid_Roll游戏说明
*游戏环境
	本游戏基于Python语言开发,要运行游戏,请确保您的设备上已经正确安装了Python3的环境,并且请确保游戏资源的完整性!请勿随意修改游戏代码!
	关于游戏资源路径问题:游戏代码中编写的为游戏资源的相对路径,请确保游戏资源相对路径与游戏代码中的一致。游戏资源data/font中提供了两种字体,有需要的可以自主更改字体或其他游戏资源,同时在代码中更新相应的资源。
*游戏说明:
	本游戏仅用作纪念南昌大学百年校庆而设计,请勿用于其他用途,游戏开发者将保留所有代码解释权
	运行方式:
	开发者一直是通过在当前目录下打开cmd,然后输入python Rapid_Roll.py运行的,若有其他更好的方式,欢迎联系我!
	玩法简介:
	游戏运行开始,需等待2~3秒,待介绍画面不动后即可按下空格键开始游戏或Q键退出游戏。
	正确运行游戏后,玩家将通过左、右按键或者A、D按键操控橙色的小球左右移动,通过控制小球不断下落到新生成的平台上,同时尽量避免落到尖刺上和尽可能多的拾取到爱心增加自身的生命值而取得更高的分数
	关于尖刺:玩家若控制小球触碰到尖刺时,玩家生命值将减一,当玩家生命值耗尽时,游戏结束,程序将自动记录您的分数,您可以选择按R键重新开始游戏。
	关于得分:游戏中设置了四个级别的难度,随着玩家存活的时间越长,平板和爱心生成的频率将降低,而尖刺出现的频率将上升,与此同时,所有对象的移动速度也会加快。每一个平板移动到最上端消失可以加一分,而每一个尖刺移动到最上端消失可以加两分
	关于游戏错误:运行游戏时,若在命令窗口提示程序进行异常,可以联系游戏开发者。
*本游戏相关代码已在CSDN上开源:https://blog.csdn.net/monster663/article/details/115678630
代码仅供参考
游戏开发者将保留所有代码解释权




Rapid_ Roll Game Description           
*Game environment            
This game is based on Python language development, to run the game, please make sure that the python 3 environment has been correctly installed on your device, and please ensure the integrity of game resources! Do not modify the game code at will!            *Game Description:  
	*This game is only designed to commemorate the centennial of Nanchang University. Please do not use it for other purposes. The game developer reserves the right to interpret all code    
Operation mode:
	Developers always open CMD in the current directory, and then enter Python rapid_ Roll.py Run, if there are other better ways, welcome to contact me!      Introduction to playing method: 
To start the game, you need to wait 2 ~ 3 seconds. After the introduction screen does not move, you can press the space bar to start the game or the Q key to exit the game.           
After running the game correctly, the player will control the orange ball to move left and right through the left and right buttons or a and D buttons. By controlling the small ball continuously falling to the newly generated platform, the player should try to avoid falling on the spikes and pick up love as much as possible to increase their own health value and obtain higher scores            
About spikes: if the player controls the ball to touch the spike, the player's HP will be reduced by 1. When the player's HP is exhausted, the game will end, and the program will automatically record your score. You can choose to restart the game by pressing the R key.            
About score: four levels of difficulty are set in the game. With the longer the player survives, the frequency of tablet and love generation will decrease, while the frequency of spikes will increase. At the same time, the movement speed of all objects will also be accelerated. One point will be added for each plate to disappear at the top, and two points will be added for each spike to disappear at the top            
About the game error: when running the game, if you prompt the program to make an exception in the command window, you can contact the game developer QQ: *****.

游戏类代码:

#game_class.py
#encoding=utf-8
import pygame
from pygame.locals import *
#彩球类
class Ball(pygame.sprite.Sprite):
	#初始化彩球的图片和位置
	def __init__(self,ball_img,init_pos,speed):
		super(Ball,self).__init__()
		self.image=ball_img
		self.rect=self.image.get_rect()
		self.rect.midbottom=init_pos
		self.speed=speed
		self.life=3
		self.fall_down=True
		self.reborn_time=False
	#彩球只能向三个方向移动,不能向上移动
	def moveLeft(self):
		self.rect.left-=self.speed
	def moveRight(self):
		
		self.rect.left+=self.speed
	def moveDown(self):
		self.rect.top+=self.speed
	def moveUp(self):
		self.rect.top-=self.speed	#此速度将和平板上升的速度一致
	def change_speed(self,speed):	#提供更改速度的接口,用于调节游戏难度
		self.speed=speed

#平板类
class Plank(pygame.sprite.Sprite):
	#初始化平板的图片和位置
	def __init__(self,plank_img,init_pos,speed):
		super(Plank,self).__init__()
		self.image=plank_img
		self.rect=self.image.get_rect()
		self.rect.topleft=init_pos
		self.speed=speed		#!!! 修改此速度时需要一同修改爱心的速度
	def move(self):
		self.rect.top-=self.speed
	def change_speed(self,speed):		#提供更改速度的接口,用于调节游戏难度
		self.speed=speed

#爱心类
class Heart(pygame.sprite.Sprite):
	def __init__(self,heart_img,init_pos,speed):
		super(Heart,self).__init__()
		self.image=heart_img
		self.rect=self.image.get_rect()
		self.rect.topleft=init_pos
		self.speed=speed		#!!! 修改此速度时需要一同修改平板的速度
	def move(self):
		self.rect.top-=self.speed
	def change_speed(self,speed):		#提供更改速度的接口,用于调节游戏难度
		self.speed=speed

#尖刺平板
class Prick(pygame.sprite.Sprite):
	def __init__(self,prick_img,init_pos,speed):
		super(Prick,self).__init__()
		self.image=prick_img
		self.rect=self.image.get_rect()
		self.rect.topleft=init_pos
		self.speed=speed
	def move(self):
		self.rect.top-=self.speed
	def change_speed(self,speed):  #提供更改速度的接口,用于调节游戏难度
		self.speed=speed
		

游戏主代码:

#encoding=utf-8
import sys,pygame
import random
import time
from pygame.locals import *
from game_class import *

#游戏界面的宽和高
screen_width=450
screen_height=660

#初始化游戏
pygame.init()
pygame.mixer.init()
screen=pygame.display.set_mode((screen_width,screen_height))

#载入背景图片
background_img=pygame.image.load('data\\img\\background1.png').convert()
background_img_rect=background_img.get_rect()

#载入游戏开始图片
game_start_img=pygame.image.load('data\\img\\gamestart.png')
game_start_img_rect=game_start_img.get_rect()

#载入游戏开始文字图片
game_start_word_img=pygame.image.load('data\\img\\game_start_word.png')
game_start_word_img_rect=game_start_word_img.get_rect()


#载入游戏结束图片
game_over_img=pygame.image.load('data\\img\\gameover.png')
game_over_img_rect=game_over_img.get_rect()

#载入游戏开始文字
#game_start_word_img=pygame.image.load('data\\img\\game_start_word.png')
#game_start_word_img_rect=game_start_word_img.get_rect()





#载入大图,取得彩球图,爱心图,平板图
images=pygame.image.load('data\\img\\img.png')
#通过set_colorkey方法设置透明键,使得图像更为兼容
images.set_colorkey((255,255,255))
#取得彩球图,爱心图,平板图,尖刺图
ball_rect=pygame.Rect(18,40,40,34)
ball_img=images.subsurface(ball_rect).convert()
#通过set_colorkey方法设置透明键,使得图像更为兼容
#ball_img.set_colorkey((255,255,255))

heart_rect=pygame.Rect(23,116,28,29)
heart_img=images.subsurface(heart_rect).convert()

plank_rect=pygame.Rect(1,1,155,20)
plank_img=images.subsurface(plank_rect).convert()

prick_rect=pygame.Rect(5,178,103,20)
prick_img=images.subsurface(prick_rect).convert()

#载入游戏声音
meet_heart_sound=pygame.mixer.Sound('data\\wav\\meet_heart.wav')

#载入尖刺声音
meet_prick_sound=pygame.mixer.Sound('data\\wav\\meet_prick.wav')

#print(type(meet_heart_sound))
#game_music_sound=pygame.mixer.music.load('data\\wav\\game_music.wav')
Scool_music_sound=pygame.mixer.music.load('data\\wav\\School_Song.mp3')
#print(type(game_music_sound))
game_over_sound=pygame.mixer.Sound('data\\wav\\game_over.wav')


#设置音量
meet_heart_sound.set_volume(0.4)
meet_prick_sound.set_volume(0.4)
pygame.mixer.music.set_volume(0.6)

#循环播放
pygame.mixer.music.play(-1,2.0)

#平板上升时会有多个图
#上升的平板
planks_up=pygame.sprite.Group()
#消失的平板
planks_over=pygame.sprite.Group()

#出现的爱心
hearts_up=pygame.sprite.Group()
#消失的爱心
hearts_over=pygame.sprite.Group()

#生成的尖刺平板
pricks_up=pygame.sprite.Group()
#消失的尖刺平板
pricks_over=pygame.sprite.Group()

'''
在设计游戏开始界面时,有两种方式,一种方式是利用Font直接写文字,通过不断刷新页面制造页面中文字的移动效果,
另一种是通过类似绘制平板的方式,写一个新的类通过文字图片的方式绘制在屏幕上
经过实际测试,我们这里选择了第二种方式
'''
def game_start():
	pygame.display.set_caption("Rapid Roll")
	screen.blit(game_start_img,game_start_img_rect)
	fre=0
	height=210
	pygame.time.Clock().tick(60)
	while True:
		'''
		time=time.time()
		if ((round(time-time_start,1)*10)% 2 ==0):	#每0.2秒修改一次位置
			game_start_word_img_rect=(20,height,217,109)q
			height-=2
		'''
		if fre%50==0:	
			game_start_word_img_rect=(20,height,217,109)
			height-=5
		fre+=1
		screen.blit(game_start_word_img,game_start_word_img_rect)
		pygame.display.update()
		if fre%1050==0:
			break
	screen.blit(game_start_img,game_start_img_rect)
	screen.blit(game_start_word_img,game_start_word_img_rect)
	while True:
		for event in pygame.event.get():
			if event.type==pygame.QUIT:
				pygame.quit()
				sys.exit()
		#如果想重新开始
		key_pressed=pygame.key.get_pressed()
		if key_pressed[K_SPACE]:
			#游戏结束以后
			#异常处理
			try:
				return 1;
			except:
				print('游戏运行异常!请联系开发人员QQ:***')
		if key_pressed[K_q]:
			pygame.quit()
			sys.exit()
def game():		#定义进行游戏的函数
	#初始化游戏变量
	pygame.display.set_caption("Rapid Roll")
	running=True
	score=0			#游戏得分
	life=3			#玩家所剩生命数
	flag=0 			#表示小球是否落到平板上
	#参数
	fre=1			#游戏共用频率参数  300一次循环
	#平板、爱心、尖刺出现的初始频率, 不能高于300
	plank_fre=25	
	heart_fre=150	
	prick_fre=60	
	#游戏事件,用于设计重生无敌时间
	time1=0
	time2=0
	#游戏时间搓,用于调整平板上升和出现的速度,游戏难度将越来越大
	game_start_time=time.time()		#获得游戏开始的时间
	game_cur_time=0
	#平板的速度
	plank_speed=5
	#实例化球类对象
	ball_init_pos=[200,230]
	ball=Ball(ball_img,ball_init_pos,plank_speed)
	while running:
		for event in pygame.event.get():
			if event.type==pygame.QUIT:
				pygame.quit()
				sys.exit()
		#控制游戏帧数
		pygame.time.Clock().tick(75)
		#-----------游戏逻辑-------------
		#若fre到达100则清零
		fre+=1
		if fre>=300:
			fre=0
		#调节各对象出现的频率
		#游戏难度调节
		game_cur_time=time.time()	#取得当前时间
		p=int(game_cur_time - game_start_time)	#获得游戏已经进行的时间
		#设置游戏难度------------------
		if p<15:		#
			plank_speed=4
			plank_fre=20
			heart_fre=65
			prick_fre=72
			ball.change_speed(plank_speed)
			#调节所有对象的移动速度
			for i in planks_up:
				i.change_speed(plank_speed)
			for i in pricks_up:
				i.change_speed(plank_speed)
			for i in hearts_up:
				i.change_speed(plank_speed)
		elif p<30:
			plank_speed=6
			plank_fre=22
			heart_fre=85
			prick_fre=55
			ball.change_speed(plank_speed)
			#调节所有对象的移动速度
			for i in planks_up:
				i.change_speed(plank_speed)
			for i in pricks_up:
				i.change_speed(plank_speed)
			for i in hearts_up:
				i.change_speed(plank_speed)
		elif p<50:
			plank_fre=25	
			heart_fre=100	
			prick_fre=55
			plank_speed=8
			ball.change_speed(plank_speed)
			#调节所有对象的移动速度
			for i in planks_up:
				i.change_speed(plank_speed)
			for i in pricks_up:
				i.change_speed(plank_speed)
			for i in hearts_up:
				i.change_speed(plank_speed)
		else:
			plank_fre=25	
			heart_fre=110	
			prick_fre=54
			plank_speed=9
			ball.change_speed(plank_speed)
			#调节所有对象的移动速度
			for i in planks_up:
				i.change_speed(plank_speed)
			for i in pricks_up:
				i.change_speed(plank_speed)
			for i in hearts_up:
				i.change_speed(plank_speed)
		#plank_rand_x=0
		#生成游戏平板
		if fre % plank_fre==0:
			rand_x=random.randint(0,430)
			plank_rand_x=rand_x
			plank_pos=[rand_x,650]
			plank_rand=Plank(plank_img,plank_pos,plank_speed)
			planks_up.add(plank_rand)		#添加新生成的平板到平板集合中去
			#生成爱心,爱心的位置将与平板相关
			if fre % heart_fre==0:
				heart_pos=[rand_x,615]
				heart_rand=Heart(heart_img,heart_pos,plank_speed)
				hearts_up.add(heart_rand)
		#生成尖刺平板
		if fre % prick_fre==0:
			#rand_x=random(random.randint(0,430))
			#while 
			prick_pos=[rand_x,650]
			prick_rand=Prick(prick_img,prick_pos,plank_speed)
			pricks_up.add(prick_rand)
		#控制平板的逻辑
		flag=0
		for move_plank in planks_up:
			move_plank.move()
			#若小球落到了一个平板上  #and move_plank.rect.top-ball.rect.top>=ball.rect.height
			if (move_plank.rect.top-ball.rect.top<=ball.rect.height and move_plank.rect.top-ball.rect.top>ball.rect.height-10) and (ball.rect.left-move_plank.rect.left<=move_plank.rect.width and ball.rect.left-move_plank.rect.left>=-ball.rect.width):
	 		#if pygame.sprite.collide_circle(move_plank,ball):
	 			flag=1
			#if pygame.sprite.collide_circle(move_plank,ball):
			if move_plank.rect.top<=0:
				score+=1
				planks_over.add(move_plank)
				planks_up.remove(move_plank)


		#控制尖刺逻辑
		for move_prick in pricks_up:
			#控制尖刺平板的移动
			move_prick.move()
			#若小球落到了尖刺平板上
			if((move_prick.rect.top-ball.rect.top<=ball.rect.height and move_prick.rect.top-ball.rect.top>0) and (ball.rect.left-move_prick.rect.left<=move_prick.rect.width and ball.rect.left-move_prick.rect.left>=-ball.rect.width+1)) and (not ball.reborn_time):
				ball.life-=1
				ball.reborn_time=True
				time1=time.time()
				ball.rect.midbottom=ball_init_pos
				meet_prick_sound.play()
			#若尖刺平板上升到最高
			if move_prick.rect.top<=0:
				score+=2
				pricks_over.add(move_prick)
				pricks_up.remove(move_prick)
				
		#判断小球是否处于重生的无敌时间
		if ball.reborn_time:
			time2=time.time()
			if int(time2-time1)<1:		#每次重生有一秒的无敌时间
				ball.reborn_time=True
			else:						#一秒以后修改无敌标志
				ball.reborn_time=False

		#调试
		#print(ball.reborn_time)
		#小球下落的逻辑	------------
		
		if flag==1 and not ball.reborn_time:	#若碰到了平板  并且不在无敌时间内
			ball.moveUp()						#小球上移
		elif flag==1 and ball.reborn_time:		#若碰到了平板  并且在无敌时间内
			pass								#小球不动
		elif flag==0 and not ball.reborn_time:	#若没有碰到平板 并且不在无敌时间内
			ball.moveDown()						#小球下移
		else:									#若没有碰到平板 并且在无敌时间内
			pass								#小球不动



		#限制小球的移动,精准判断
		#触碰左边界
		if(ball.rect.left<=0):
			ball.rect.left=0
		#触碰右边界
		if(screen_width-ball.rect.left<=ball.rect.width):
			ball.rect.left=screen_width-ball.rect.width
		#触碰上边界
		if(ball.rect.top<=0) and (not ball.reborn_time):
			ball.life-=1
			ball.reborn_time=True
			time1=time.time()
			ball.rect.midbottom=ball_init_pos	#每次死亡以后初始化小球位置
		#触碰下边界
		if(screen_height-ball.rect.top<=ball.rect.height) and (not ball.reborn_time):
			ball.life-=1
			ball.reborn_time=True
			time1=time.time()
			ball.rect.midbottom=ball_init_pos

		#控制爱心的逻辑
		for move_heart in hearts_up:
			move_heart.move()
			if move_plank.rect.top<=0:
				hearts_over.add(move_heart)
				hearts_up.remove(move_heart)
			#若爱心和小球相遇
			if pygame.sprite.collide_circle(move_heart,ball):
				hearts_over.add(move_heart)
				hearts_up.remove(move_heart)
				ball.life+=1
				#print(type(meet_heart_sound))
				meet_heart_sound.play()

		#游戏结束的逻辑
		if ball.life<=0:
			running=False
		#在游戏界面绘制图形
		screen.fill(0)
		screen.blit(background_img,background_img_rect)

		#绘制小球	若小球在重生时段,每0.2秒绘制一次图形,提供闪烁效果
		if running:
			if not ball.reborn_time:
				screen.blit(ball.image,ball.rect)
			if ball.reborn_time:
				#time2=time.time()
				#每0.2秒打印一次小球图案,制造无敌闪烁效果
				if ((round(time2-time1,1)*10)% 2 ==0):	#time2已经取得了当前的时间
					screen.blit(ball.image,ball.rect)


		#绘制平板和爱心
		planks_up.draw(screen)
		hearts_up.draw(screen)
		#绘制尖刺平板
		pricks_up.draw(screen)

		#显示积分
		score_font=pygame.font.Font('data\\font\\font.ttf',25)
		score_text=score_font.render('Your Score:'+str(score),True,(200,150,81))
		score_text_rect=score_text.get_rect()
		screen.blit(score_text,score_text_rect)

		#显示剩余生命数:
		life_font=pygame.font.Font('data\\font\\font.ttf',25)
		life_text=life_font.render('Remaining life:'+str(ball.life),True,(222,67,101))
		life_text_rect=life_text.get_rect()
		#调试
		#print(type(life_text_rect))
		#print(life_text_rect)
		#修改显示剩余生命的位置
		life_text_rect=[0,30,131,45]
		screen.blit(life_text,life_text_rect)
		#ball.draw(screen)
		#监听事件:
		key_pressed=pygame.key.get_pressed()
		if running:
			if key_pressed[K_LEFT] or key_pressed[K_a]:
				ball.moveLeft()
			if key_pressed[K_RIGHT] or key_pressed[K_d]:
				ball.moveRight()

		pygame.display.update()
	if not running:
		#游戏结束以后,清除当前游戏数据
		for i in planks_up:
			planks_up.remove(i)
		for i in pricks_up:
			pricks_up.remove(i)
		for i in hearts_up:
			hearts_up.remove(i)
		return score
#游戏开始
#异常处理
def game_over(game_score):
	#游戏结束以后
	#先绘制背景图
	screen.blit(game_over_img,game_over_img_rect)
	game_over_sound.play()

	#绘制本局游戏得分
	final_score_font=pygame.font.Font('data\\font\\font.ttf',53)
	final_score_text=final_score_font.render('You Final score is:',True,(0,0,0))
	final_score_rect=(15,120,200,59)
	score_font=pygame.font.Font('data\\font\\font.ttf',100)
	score_text=score_font.render(str(game_score),True,(0,0,0))
	score_rect=(190,180,46,116)

	#重新进入游戏
	restart_font=pygame.font.Font('data\\font\\font.ttf',32)
	restart_text=restart_font.render('Press R to Restart Game...',True,(3,8,8))
	restart_rect=(50,550,400,59)

	#将游戏成绩数据写道当前目录下Game_Score.txt文件内
	file=open('Game_Score.txt','a',encoding='utf-8')
	time_arry=time.localtime(int(time.time()))
	other_style_time=time.strftime('%Y-%m-%d %H:%M:%S',time_arry)
	#print(other_style_time)
	file.write(str(game_score)+str(' ')+other_style_time+str('\n'))
	file.close()

	#计算历史最高纪录
	f=open('Game_Score.txt','r',encoding='utf-8')
	scores=[]
	#读取历史游戏成绩
	for line in f:
		scores.append(int(line.split(' ')[0]))	#成绩与时间之间用空格分开,取得第一个数字
	quick_sort(scores,0,len(scores)-1)
	scores.reverse()
	highest_score=scores[0]

	highest_score_font=pygame.font.Font('data\\font\\font.ttf',50)
	highest_score_text=highest_score_font.render('The highest Score:',True,(12,12,12))
	#highest_score_rect=highest_score_text.get_rect()
	highest_score_rect=(50,410,387,82)

	high_score_font=pygame.font.Font('data\\font\\font.ttf',75)
	high_score_text=high_score_font.render(str(highest_score),True,(12,12,12))
	high_score_rect=(190,460,75,99)
	#绘制所有元素
	screen.blit(final_score_text,final_score_rect)
	screen.blit(score_text,score_rect)
	screen.blit(restart_text,restart_rect)
	screen.blit(highest_score_text,highest_score_rect)
	screen.blit(high_score_text,high_score_rect)
	pygame.display.update()
def arr_depart(arr,left,right):   
    k=arr[left] #第一位元素当成基准数
    while left<right: 
          while left<right and  arr[right]>=k:
                right=right-1 
          if left<right:#要换位置的
             arr[left],arr[right]=arr[right],arr[left]
          while left<right and arr[left]<k:
              left=left+1 #不用动
          if left<right:
             arr[right],arr[left]=arr[left],arr[right]            
    return left
def quick_sort(arr,left,right):
	if(left<right):
		base_index=arr_depart(arr,left,right)
		quick_sort(arr,0,base_index)
		quick_sort(arr,base_index+1,right)

#游戏运行流程		
game_score=0
try:
	f=game_start()
	if f==1:
		game_score=game()
except:
	print('游戏开始---程序运行异常!请联系开发人员QQ:***')
#游戏结束时
game_over(game_score)



while True:
	for event in pygame.event.get():
		if event.type==pygame.QUIT:
			pygame.quit()
			sys.exit()
	#如果想重新开始
	key_pressed=pygame.key.get_pressed()
	if key_pressed[K_r]:
		#游戏结束以后
		#异常处理
		try:
			game_score=game()
		except:
			print('游戏开始---程序运行异常!请联系开发人员QQ:***')
		game_over(game_score)

游戏资源

回头在这补一个链接,需要的也可以私信我

以上代码仅供参考,若还有疑问欢迎评论留言

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

monster663

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值