用Python完成游戏从:小笨鸟,到小飞鸟,同时将单机游戏,变成联网游戏
在B站学习UP主:趣派编程,“99%相似度!手把手教你用Python制作Flappy Bird像素鸟游戏!“ 后有感而发。
单独的一只小笨鸟多么的无聊
在UP主:趣派编程,做的项目下,原本的小笨鸟有三种颜色,分别是黄色,蓝色,红色,所以我想,能不能做成三种属性的鸟,说做就做,我将蓝色,定义为鹰,速度会更快,我将红色定义为火烈鸟,跳得高,且速度快。每到10,修改一种状态。 在如此设想下,我们就只需要修改,game_window()中,得分判定后的代码,同时提前添加temp= 0在while Ture之前,这里的eagle,falcon是自己找的素材,为鹰叫和另一种鸟叫。
if bird.rect.left + first_pipe_up.x_vel < first_pipe_up.rect.centerx<bird.rect.left:
AUDIO['score'].play()
score +=1
temp = score%10
if temp==0:
times+=1
times %=3
if times ==1:
AUDIO['eagle'].play()
if bird.rect.left + first_pipe_up.x_vel < first_pipe_up.rect.centerx<bird.rect.left:
AUDIO['eagle'].stop()
AUDIO['score'].play()
bird.color='blue'
for pipe in pipe_group.sprites():
pipe.x_vel = -5
if times== 2:
AUDIO['falcon'].play()
if bird.rect.left + first_pipe_up.x_vel < first_pipe_up.rect.centerx<bird.rect.left:
AUDIO['falcon'].stop()
AUDIO['score'].play()
bird.color='red'
for pipe in pipe_group.sprites():
pipe.x_vel = -7
PIPE_GAP=120
if times==0:
bird.color='yellow'
for pipe in pipe_group.sprites():
pipe.x_vel = -4
修改鸟类中的参数,定义在红色的时候,增加跳高,同时修改鸟的颜色,这样在main函数中就不用导入小鸟了。
class Bird:
def __init__(self,x,y):
self.color = 'yellow'
self.frames = [0] * REPEAT + [1]*REPEAT+[2]*REPEAT +[1]*REPEAT
self.idx = 0
self.images = [IMAGES[self.color+'-up'],IMAGES[self.color+'-mid'],IMAGES[self.color+'-down']]
self.image = self.images[self.frames[self.idx]]
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.y_vel = -10
self.max_y_vel = 10
self.gravity = 1
self.rotate = 45
self.max_rotate = -20
self.rotate_vel = -3
self.y_vel_after_flap = -10
self.rotate_after_flap = 45
self.dying = False
def update(self,flap=False):
self.images = [IMAGES[self.color+'-up'],IMAGES[self.color+'-mid'],IMAGES[self.color+'-down']]
if flap:
self.y_vel = self.y_vel_after_flap
self.rotate = self.rotate_after_flap
if self.color == 'red':
self.y_vel = -12
self.y_vel = min(self.y_vel +self.gravity,self.max_y_vel)
self.rect.y +=self.y_vel
self.rotate = max(self.rotate+self.rotate_vel,self.max_rotate)
self.idx +=1
self.idx %= len(self.frames)
self.image = self.images[self.frames[self.idx]]
self.image = pygame.transform.rotate(self.image,self.rotate)
def go_die(self):
if self.rect.y<FLOOR_Y:
self.rect.y +=self.max_y_vel
self.rotate = -90
self.image = self.images[self.frames[self.idx]]
self.image = pygame.transform.rotate(self.image,self.rotate)
else:
self.dying=False
第二个功能:联网,这里就是制作排行榜
最后有一个自己的服务器,或者内网穿透也可以
服务器端,本来是想用socket,但是不会,而且个人觉得两端通讯,socket对于非同在一个局域网,或非公网IP下交流是有问题的,私网IP是可以发送数据到公网iP,但是怎么回来呢,公网IP下的服务器是不能通过私网iP发送信息的,所以干脆直接做成服务器的模式,在游戏中采用get请求,获取用户和得分信息,在游戏中采用post请求,发送用户和得分信息,剩下的,交给服务器端接受处理即可。 服务器端代码如下:需要提前创建好Flappy表,定义好:username,goal,数据,tip:goal最好定义为int型,因为排行榜要以分数作降序排列。
import pymysql
def get_conn():
conn = pymysql.connect(host='localhost', port=3306, user='****', passwd='*****', db='****',charset='utf8')
return conn
def update(sql,args):
conn = get_conn()
cur = conn.cursor()
result = cur.execute(sql,args)
conn.commit()
cur.close()
conn.close()
def insert(sql, args):
conn = get_conn()
cur = conn.cursor()
result = cur.execute(sql, args)
conn.commit()
cur.close()
conn.close()
def My_insert(username,goal):
sql='INSERT INTO Flappy VALUES(%s,%s)'
insert(sql,(username,goal))
def query(sql):
result = []
conn = get_conn()
cur = conn.cursor()
cur.execute(sql)
results = cur.fetchall()
a = 0
for row in results:
a +=1
if a > 3:
continue
username = row[0]
goal = row[1]
result.append(username)
result.append(goal)
return result
def query2(sql,args):
result = []
conn = get_conn()
cur = conn.cursor()
cur.execute(sql,args)
results = cur.fetchall()
a = 0
for row in results:
a +=1
if a > 3:
continue
username = row[0]
goal = row[1]
result.append(username)
result.append(goal)
return result
def My_Find():
sql = 'SELECT * FROM Flappy order by goal desc'
result = query(sql)
if result == []:
err=True
return result,err
else:
err = False
return result,err
def My_FindName(username):
sql = 'SELECT * FROM Flappy where username=%s;'
args = username
result = query2(sql,args)
if result == []:
err=True
return result,err
else:
err = False
return result,err
def Update_Score(username,goal):
sql = 'UPDATE Flappy SET goal = %s WHERE username = %s'
args = (goal,username)
update(sql,args)
from flask import Flask,jsonify
import json
app = Flask(__name__)
app.config['SECRET_KEY'] = '123456'
from flask import Flask, request
@app.route('/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
json_user_infos = request.get_data()
user_infors = json.loads(json_user_infos.decode('utf8'))
username = user_infors.get("name")
goal = int(user_infors.get("goal"))
result,err = My_FindName(username)
if err:
My_insert(username,goal)
else:
if goal <= int(result[1]):
return "200"
else:
Update_Score(username,goal)
return "200"
result,err = My_Find()
user_dicts = {}
num = 0
num_sum=0
user_dict = {}
for a in result:
num+=1
if num==1:
user_dict["name"] = a
if num==2:
user_dict["goal"] = a
num_sum+=1
num=0
user_dicts[str(num_sum)] = user_dict
user_dict= {}
json_data = json.dumps(user_dicts)
return json_data
if __name__ == '__main__':
app.run(host='127.0.0.1', port=****, debug=True)
获取数据当然要写入数据,我们只需要发请求,接收数据,输出到屏幕上即可,这里输出方式,当然是还是参考UP主:趣派编程,中的99%相似度!手把手教你用Python制作超级玛丽游戏,说实话,这个超级玛丽怎么还没更新完!!!哈哈哈,在这里还是感谢UP主的无私奉献(这是不要钱就能看的吗!😊🐼) 上代码:
def end_window(result):
gameover_x = (W-IMAGES['gameover'].get_width())/2
gameover_y = (FLOOR_Y - IMAGES['gameover'].get_height())/2
bird = result['bird']
pipe_group = result['pipe_group']
score = result['score']
data = {}
data["name"] = getpass.getuser()
data["goal"] = score
res = requests.post(url=URL,data=json.dumps(data))
res = requests.get(URL)
RankList = res.json()
while True:
if bird.dying:
bird.go_die()
else:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.display.quit()
quit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
return
bird.go_die()
SCREEN.blit(IMAGES['bgpic'],(0,0))
pipe_group.draw(SCREEN)
SCREEN.blit(IMAGES['floor'],(0,FLOOR_Y))
show_score(score)
SCREEN.blit(IMAGES['gameover'],(gameover_x,gameover_y))
SCREEN.blit(bird.image,bird.rect)
label_draw(SCREEN,RankList)
pygame.display.update()
CLOCK.tick(FPS)
def create_label(label,size=40,width_scale=1.25,height_scale=1):
font = pygame.font.SysFont('FixedSys.ttf',size)
label_image = font.render(str(label),1,(255,255,255))
rect = label_image.get_rect()
label_image = pygame.transform.scale(label_image,(int(rect.width*width_scale),
int(rect.height*height_scale)))
return label_image
def label_draw(SCREEN,RankList):
num_list = len(RankList)
info_labels = []
info_labels.append((create_label("Forbes list"),(55,5)))
for i in range(1,num_list+1):
info_labels.append((create_label(RankList[str(i)]["name"]),(10,30+i*50)))
info_labels.append((create_label(RankList[str(i)]["goal"]),(200,30+i*50)))
for label in info_labels:
SCREEN.blit(label[0],label[1])
要是能自己更新游戏的难易程度就好了!
提示:可以的话也可以像马里奥哪样加个开局选择难度的,但是我不想敲太多代码了!!!
所以我想,既然游戏获取数据可以用服务器,更新难易程度干嘛不直接从服务器获取呢,这样不就可以少写好多代码了吗! 上代码,服务器端在原来的基础上,add
@app.route('/update', methods=['GET', 'POST'])
def index():
User_Grade = {}
User_Grade["distance"] = "200"
User_Grade["pipe_gap"] = "110"
print(User_Grade)
json_data = json.dumps(User_Grade)
return json_data
游戏端添加,同时把以前的game_window():函数中的distance,pipe_gap改掉
URL = '****'
URL_UPDATE = '****/update'
RES_GRADE = requests.get(URL_UPDATE)
GRADE = RES_GRADE.json()
DISTANCE = int(GRADE["distance"])
PIPE_GAP = int(GRADE["pipe_gap"])
以上就完成了所有代码的修改。 **
**
|