Pygame实现小笨鸟,到小飞鸟

Pygame实现小笨鸟,到小飞鸟,第1张

用Python完成游戏从:小笨鸟,到小飞鸟,同时将单机游戏,变成联网游戏

在B站学习UP主:趣派编程,“99%相似度!手把手教你用Python制作Flappy Bird像素鸟游戏!“ 后有感而发。

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
#MySql
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)

# coding:utf-8
from flask import Flask,jsonify
import json
# 创建app应用,__name__是python预定义变量,被设置为使用本模块.
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))#URL是自己服务器的url
    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"])

以上就完成了所有代码的修改。
**

源程序下载

**

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/732927.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存