管理信息系统第二学期课程设计

----------系统概要-------------
1. 基于python3版本,flask框架开发的新闻平台,采用前后端不分离的方式
2. 具有基本登陆,注册
3. 用户可以进行新闻的发布修改
4. 用户可以修改个人信息
5. 在新闻详细页具体关注新闻,关注作者,发表评论,回复评论等功能
6. 后台管理,管理员可以对新闻进行审核,并新增新闻分类

---------网站结构设计-------------
1.新闻主页,可以查看新闻列表,最热新闻,查看不同分类的新闻,通过ajax进行局部刷新,往下滑自动加载下一页
2.用户登陆,注册
3.新闻详细页,有评论点赞,作者信息
4.用户个人中心,修改个人信息,发布信息,查看关注作者
5.后台管理,新闻全部信息,审核新闻,增加分类

------------模块详细设计-----------

登陆注册模块

登陆
@user_blueprint.route(‘/login‘, methods=[‘POST‘])
def login():
    # 接收数据
    dict1 = request.form
    mobile = dict1.get(‘mobile‘)
    pwd = dict1.get(‘pwd‘)

    # 验证有效性
    if not all([mobile, pwd]):
        return jsonify(result=1)

    # 查询判断、响应
    user = UserInfo.query.filter_by(mobile=mobile).first()
    # 判断mobile是否正确
    if user:
        # 进行密码对比,flask内部提供了密码加密、对比的函数
        if user.check_pwd(pwd):
            # 将当前时段的登录数量+1
            login_time_count()
            # 状态保持
            session[‘user_id‘] = user.id
            # 返回成功的结果
            return jsonify(result=4, avatar=user.avatar_url, nick_name=user.nick_name)
        else:
            # 密码错误
            return jsonify(result=3)
    else:
        # 如果查询不到数据返回None,表示mobile错误
        return jsonify(result=2)

注册模块
ef register():
    # 接收数据
    dict1 = request.form
    mobile = dict1.get(‘mobile‘)
    yzm_image = dict1.get(‘yzm_image‘)
    yzm_sms = dict1.get(‘yzm_sms‘)
    pwd = dict1.get(‘pwd‘)

    # 验证数据的有效性
    # 保证所有的数据都被填写,列表中只要有一个值为False,则结果为False
    if not all([mobile, yzm_image, yzm_sms, pwd]):
        return jsonify(result=1)
    # 对比图片验证码
    if yzm_image != session[‘image_yzm‘]:
        return jsonify(result=2)
    # 对比短信验证码
    if int(yzm_sms) != session[‘sms_yzm‘]:
        return jsonify(result=3)
    # 判断密码的长度
    import re
    if not re.match(r‘[a-zA-Z0-9_]{6,20}‘, pwd):
        return jsonify(result=4)
    # 验证mobile是否存在
    mobile_count = UserInfo.query.filter_by(mobile=mobile).count()
    if mobile_count > 0:
        return jsonify(result=5)

    # 创建对象
    user = UserInfo()
    user.nick_name = mobile
    user.mobile = mobile
    user.password = pwd
    # user.avatar = ‘cat.jpg‘
    # 提交到数据库
    try:
        db.session.add(user)
        db.session.commit()
    except:
        current_app.logger_xjzx.error(‘用户注册访问数据库失败‘)
        return jsonify(result=7)

    # 返回响应
    return jsonify(result=6)

访问其他视图时,验证是否登陆(装饰器)

def login_required(view_fun):
    @functools.wraps(view_fun)  # 保持view_fun的函数名称不变,不会被fun2这个名称代替
    def fun2(*args, **kwargs):
        # 判断用户是否登录
        if ‘user_id‘ not in session:
            return redirect(‘/‘)
        # 视图执行完,会返回response对象,此处需要将response对象继续return,最终交给浏览器
        return view_fun(*args, **kwargs)

    return fun2

管理员模块

管理员登陆
@admin_blueprint.route(‘/login‘, methods=[‘GET‘, ‘POST‘])
def login():
    if request.method == ‘GET‘:
        return render_template(‘admin/login.html‘)
    elif request.method == ‘POST‘:
        # 接收
        dict1 = request.form
        mobile = dict1.get(‘username‘)
        pwd = dict1.get(‘password‘)
        # 验证
        if not all([mobile, pwd]):
            return render_template(
                ‘admin/login.html‘,
                msg=‘请填写用户名、密码‘
            )
        # 处理
        user = UserInfo.query.filter_by(isAdmin=True, mobile=mobile).first()
        if user is None:
            return render_template(
                ‘admin/login.html‘,
                mobile=mobile,
                pwd=pwd,
                msg=‘用户名错误‘
            )
        if not user.check_pwd(pwd):
            return render_template(
                ‘admin/login.html‘,
                mobile=mobile,
                pwd=pwd,
                msg=‘密码错误‘
            )
        # 登录成功后,进行状态保持
        session[‘admin_user_id‘] = user.id
        # 响应
        return redirect(‘/admin/‘)
访问其他视图,验证是否登陆状态(请求勾子)
@admin_blueprint.before_request
def login_validate():
    # 对于不执行这段代码的视图,可以进行排除
    except_path_list = [‘/admin/login‘]
    if request.path not in except_path_list:
        if ‘admin_user_id‘ not in session:
            return redirect(‘/admin/login‘)
        g.user = UserInfo.query.get(session[‘admin_user_id‘])

新闻模块

展示新闻列表
@news_blueprint.route(‘/newslist‘)
def newslist():
    # 查询新闻数据==>[news,news,...]==>json
    # 接收请求的页码值
    page = int(request.args.get(‘page‘, ‘1‘))
    # 查询新闻信息
    pagination = NewsInfo.query.filter_by(status=2)
    # 接收分类的编号
    category_id = int(request.args.get(‘category_id‘, ‘0‘))
    if category_id:
        pagination = pagination.filter_by(category_id=category_id)
    # 排序,分页
    pagination = pagination.         order_by(NewsInfo.update_time.desc()).         paginate(page, 4, False)
    # 获取当前页的数据
    news_list = pagination.items
    # pagination.pages
    # 将python语言中的类型转换为json
    news_list2 = []
    for news in news_list:
        # print(news.pic_url)
        news_dict = {
            ‘id‘: news.id,
            ‘pic‘: news.pic_url,
            ‘title‘: news.title,
            ‘summary‘: news.summary,
            ‘user_avatar‘: news.user.avatar_url,
            ‘user_nick_name‘: news.user.nick_name,
            ‘update_time‘: news.update_time.strftime(‘%Y-%m-%d‘),
            ‘user_id‘: news.user.id,
            ‘category_id‘: news.category_id
        }
        news_list2.append(news_dict)

    return jsonify(news_list=news_list2)

新闻首页
@news_blueprint.route(‘/‘)
def index():
    # 查询分类,用于显示
    category_list = NewsCategory.query.all()

    # 判断用户是否登录
    if ‘user_id‘ in session:
        user = UserInfo.query.get(session[‘user_id‘])
    else:
        user = None

    # 获取分类排行前6条数据select * from ... where ... order ... limit 6
    count_list = NewsInfo.query.                      filter_by(status=2).                      order_by(NewsInfo.click_count.desc())[0:6]

    return render_template(
        ‘news/index.html‘,
        category_list=category_list,
        user=user,
        count_list=count_list
    )

1. 用户views_user.py模块
注册
本质:向用户表中加入数据
展示页面
views_news.py
index.html
图片验证码
使用python的绘图工具PIL进行绘制,返回给浏览器
pip install pillow
拷贝captcha到utils包
在views_user.py定义视图
在index.html中调用
看不清换一张
短信验证码
调用第三方的接口进行短信处理
拷贝sdk
定义调用代码ytx_send.py
在views_user.py中定义视图
在js中调用
注册处理views_user.py
使用post方式请求
CSRF保护
在app对象上进行保护
csrf_token()
接收数据
验证数据的有效性
创建user对象并赋值
提交到数据库
响应
调用
登录
本质:根据用户名密码查询数据
视图处理
获取数据
有效性判断
处理:查询
判断响应:用户名、密码
登录成功后状态保持
调用
退出
右上角信息显示
登录视图中返回用户信息
登录处理中显示信息
视图:删除cookie值
调用
用户中心
视图index
模板user.html
展示昵称、头像
完善链接
user.html
定义相关视图
user.html代码重用
定义base.html,封装头、尾
在user.html中继承
登录验证
在访问用户中心的相关视图时,必须登录,否则转到首页
定义装饰器
添加到视图函数上
在用户中心退出时转到首页
基本资料
显示原有数据
视图:查询
模板:展示
提交处理
使用ajax+post
视图:接收数据并修改对象
调用:提交,成功后修改页面
头像设置
展示
视图:查询
模板:展示
如何在flask中进行图片上传
将文件上传到服务器,保存在磁盘上,然后将文件名保存在表的字段上
HTML要求
form表单的method="post"
表单的 enctype="multipart/form-data"
flask处理
接收文件request.files.get(‘与input的name一致‘)
保存:文件对象.save(路径)
将文件名赋给对象的属性:文件对象.name
将文件上传到七牛云
如何使用ajax方式进行文件上传:jquery.form.min.js
提交
视图处理
调用及成功后显示
访问腾讯云的图片
我的关注
查询数据并展示
视图中查询
模板中展示
添加示例数据:
user_info,tb_user_follow
分页
查询语句中有方法paginate(页码,页大小,False)
在视图中分页查询
在模板中调用jquery.pagination.min.js
我的收藏
视图:查询并分页
模板:展示,页码控制
新闻列表
视图:查询并分页
模板:展示,页码控制
密码修改
展示
定义视图
模板显示
处理
post
问题分析
视图处理
响应
新闻发布
展示
定义视图:查询新闻分类
模板显示
处理
视图接收添加
页面news_list.html
main.js
新闻修改
展示
视图:查询数据
模板:展示
处理
视图:接收并保存
转到列表页

2. 新闻views_news.py模块

功能分析
首页
新闻列表
分页(向下滑动,到底部时加载)
显示分类
指定分类的列表+分页
登录状态
点击量排行列表
模板继承
详情页
模板继承
根据新闻编号查询新闻并展示
收藏与取消收藏
评论
评论列表
回复评论
点赞评论
作者信息
关注与取消关注
点击排行(重用:宏)
首页
定义视图,显示页面
模板继承
继承自base.html
index.html
所有分类
视图
模板
登录状态
视图
模板base.html
main.js
views_user中的login视图
新闻列表
使用ajax方式查询数据
使用vue渲染页面
视图news_list:查询
复制vue.js到项目中
显示:index.html
index.js
函数updateNewsData
分页
当进行$.get()请求后,数据不会立即返回,但是<100的判断还在执行,这样会发起多次请求,解决:增加一个请求标志
视图
index.js
分类数据查询
视图
如果请求是第一页,则直接为vue赋值
如果请求非第一页,则为vue的数组进行拼接
index.js中请求调用
分页的完善:index.js
updateNewsData
点击排行
在index.html中显示
详情页
定义视图,展示页面
app.py中处理404
视图函数detail
模板继承
登录状态
显示新闻信息{{news.***}}
点击排行:重用(宏)
macro.html
index.html使用
detail.html使用
视图中查询点击排行数据
收藏
如果当前新闻的作者与当前登录的用户是同一个账户,则不显示收藏的按钮
定义视图:数据添加
在detail.html中加入新闻编号、口令
使用ajax请求视图
取消收藏-视图
取消收藏-调用
添加评论
定义视图,添加数据
js调用
界面提示
评论列表
ajax+vue
定义视图,查询数据,返回json
js调用:$.get()
vue模板定义
在js中创建vue对象并调用
点赞
post,局部刷新
定义视图,处理数据,user_id-comment_id,存储在redis中
js调用
界面样式切换
commentlist视图
app.py
detail.html中的vue模板
取消点赞
视图中处理
js中调用
回复
定义视图,添加数据
js调用$.post
展示

关注
定义视图,处理数据
默认展示效果
$.post()调用

3. 后台views_admin.py 模块

后台views_admin.py
功能分析
登录
登出
后台管理页面
访问验证
用户统计
用户列表
新闻审核列表
新闻审核
新闻版式编辑列表
新闻版式编辑
新闻分类管理(局部刷新)
创建管理员
方案一:直接在数据库中执行insert语句
方案二:直接在前台注册,在表中修改isAdmin属性
解决:扩展终端命令,进行添加管理员
创建命令类super_command.py
添加扩展命令xjzx.py
登录
定义视图,展示页面
模板login.html
接收post请求,查询数据,状态保持
后台主页
定义视图
修改模板:维护链接
用户信息
菜单的修改
退出
定义视图
登录验证
判断是否登录,如果未登录则转到登录页面
大部分视图都要进行这个验证,除了/admin/login
方案一:装饰器(已经在用户中心中使用过)
方案二:请求勾子before_request
用户统计
定义视图
展示页面
需要展示的数据
用户总数
用户月新增数
用户日新增数
用户登录活跃数
注册登录
登录分时统计
登录成功时写数据(views_user.py==>login)
在用户统计时读数据
用户列表
定义视图:展示页面
展示模板vue
定义视图:返回json数据
新闻审核列表
展示视图
展示模板
列表视图
新闻版式编辑列表
展示视图
展示模板
列表视图
新闻审核列表-搜索
视图
html
js调用
新闻版式编辑列表-搜索
视图
html
js调用
新闻审核
get请求视图,展示页面
模板
post请求视图,修改新闻状态
新闻版式编辑
get视图
模板
post视图
新闻分类管理
无刷新
页面视图
模板vue
json视图
js调用news_type.js
添加
视图
js
修改
视图
js

-----------数据结构和算法-------------
1. 将常用的数据存入redis数据库提升数据查询效率
。。。。。。。

-----------数据库设计--------------

ORM(数据库设计)

import pymysql
from flask import current_app
from werkzeug.security import generate_password_hash, check_password_hash

pymysql.install_as_MySQLdb()

from flask_sqlalchemy import SQLAlchemy

db=SQLAlchemy()

from datetime import datetime
class BaseModel(object):
    create_time=db.Column(db.DateTime,default=datetime.now)
    update_time=db.Column(db.DateTime,default=datetime.now)
    isDelete=db.Column(db.Boolean,default=False)

tb_news_collect = db.Table(
    ‘tb_news_collect‘,
    db.Column(‘user_id‘, db.Integer, db.ForeignKey(‘user_info.id‘), primary_key=True),
    db.Column(‘news_id‘, db.Integer, db.ForeignKey(‘news_info.id‘), primary_key=True)
)
tb_user_follow = db.Table(
    ‘tb_user_follow‘,
    db.Column(‘origin_user_id‘, db.Integer, db.ForeignKey(‘user_info.id‘), primary_key=True),
    db.Column(‘follow_user_id‘, db.Integer, db.ForeignKey(‘user_info.id‘), primary_key=True)
)

class NewsCategory(db.Model, BaseModel):
    __tablename__ = ‘news_category‘
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(10))
    #关系属性:不会在表中生成字段
    #lazy=‘dynamic‘惰性加载category.news
    #category=NewsCategory.query.get(1)
    #当使用lazy=‘dynamic‘时不会查询分类的新闻信息
    #这样设置的好处:可能本次只是使用分类对象,不想使用新闻对象,则可以减少数据库的查询量
    news = db.relationship(‘NewsInfo‘, backref=‘category‘, lazy=‘dynamic‘)

class NewsInfo(db.Model, BaseModel):
    __tablename__ = ‘news_info‘
    id = db.Column(db.Integer, primary_key=True)
    category_id = db.Column(db.Integer, db.ForeignKey(‘news_category.id‘))
    pic = db.Column(db.String(50))
    title = db.Column(db.String(30))
    summary = db.Column(db.String(200))
    content = db.Column(db.Text)
    user_id = db.Column(db.Integer, db.ForeignKey(‘user_info.id‘))
    click_count = db.Column(db.Integer, default=0)
    comment_count = db.Column(db.Integer, default=0)
    #1--待审核,2--通过,3--拒绝
    status = db.Column(db.SmallInteger, default=1)
    reason=db.Column(db.String(100),default=‘‘)
    comments = db.relationship(‘NewsComment‘, backref=‘news‘, lazy=‘dynamic‘, order_by=‘NewsComment.id.desc()‘)

    @property
    def pic_url(self):
        from config import Config
        return Config.tengxun_URL + self.pic

    # def to_index_dict(self):
    #     return {
    #         ‘id‘: self.id,
    #         ‘pic_url‘: self.pic_url,
    #         ‘title‘: self.title,
    #         ‘summary‘: self.summary,
    #         ‘author‘: self.user.nick_name,
    #         ‘author_avatar‘: self.user.avatar_url,
    #         ‘author_id‘: self.user_id,
    #         ‘udpate_time‘: self.update_time.strftime(‘%Y-%m-%d‘)
    #     }

class UserInfo(db.Model,BaseModel):
    __tablename__ = ‘user_info‘
    id = db.Column(db.Integer, primary_key=True)
    avatar = db.Column(db.String(50), default=‘user_pic.png‘)
    nick_name = db.Column(db.String(20))
    signature = db.Column(db.String(200),default=‘这货很懒,什么也没写‘)
    public_count = db.Column(db.Integer, default=0)
    follow_count = db.Column(db.Integer, default=0)
    mobile = db.Column(db.String(11))
    password_hash = db.Column(db.String(200))
    gender = db.Column(db.Boolean, default=False)
    isAdmin = db.Column(db.Boolean, default=False)
    #用户发布新闻为1:多,所以将新闻关联属性定义在User类中
    news = db.relationship(‘NewsInfo‘, backref=‘user‘, lazy=‘dynamic‘)
    #用户对评论为1:多,所以将评论关联属性定义在User类中
    comments = db.relationship(‘NewsComment‘, backref=‘user‘, lazy=‘dynamic‘)
    #用户对收藏新闻为多:多,此时关系属性可以定义在任意类中,当前写在了User类中
    news_collect = db.relationship(
        ‘NewsInfo‘,
        #多对多时,指定关系表,因为外键存储在这个关系表中
        secondary=tb_news_collect,
        lazy=‘dynamic‘
        #此处没有定义backref,作用是根据新闻找用户,因为不需要使用这个功能,所以可以不定义
    )
    #用户关注用户为自关联多对多,关系属性只能定义在User类中
    #使用user.follow_user可以获得当前user用户关注的用户列表
    #select * from users inner join tb_user_follow on user.id=origin_user_id
    follow_user = db.relationship(
        ‘UserInfo‘,
        #多对多,所以指定关系表
        secondary=tb_user_follow,
        lazy=‘dynamic‘,
        #user.follow_by_user可以获得当前user用户的粉丝用户列表
        backref=db.backref(‘follow_by_user‘, lazy=‘dynamic‘),
        #在使用user.follow_user时,user.id与关系表中哪个字段判等
        primaryjoin=id == tb_user_follow.c.origin_user_id,
        #在使用user.follow_by_user时,user.id与关系表中的哪个字段判等
        secondaryjoin=id == tb_user_follow.c.follow_user_id
    )

    @property
    def password(self):
        pass

    @password.setter
    def password(self, pwd):
        self.password_hash = generate_password_hash(pwd)

    def check_pwd(self, pwd):
        return check_password_hash(self.password_hash, pwd)

    @property#user.avatar_url()==>user.avatar_url
    def avatar_url(self):
        from config import Config
        # print(Config.tengxun_URL)
        return Config.tengxun_URL+self.avatar

class NewsComment(db.Model, BaseModel):
    __tablename__ = ‘news_comment‘
    id = db.Column(db.Integer, primary_key=True)
    news_id = db.Column(db.Integer, db.ForeignKey(‘news_info.id‘))
    user_id = db.Column(db.Integer, db.ForeignKey(‘user_info.id‘))
    like_count = db.Column(db.Integer, default=0)
    comment_id = db.Column(db.Integer, db.ForeignKey(‘news_comment.id‘))
    msg = db.Column(db.String(200))
    #关联属性,用于获取当前评论的回复数据
    comments = db.relationship(‘NewsComment‘, lazy=‘dynamic‘)

1. 新闻分类(category)
id, name, is_delete
2.新闻(news_info)
id, title, category_id(category外键) ,pic ,summary ,context ,user_id(user外键) ,source ,click_count ,comment_count ,status ,reason

3.用户关注用户关系
用户关注用户,自关联多对多

4. 用户收藏新闻关系表
用户与新闻一对多

5, 用户

6. 评论

原文地址:https://www.cnblogs.com/Betty18/p/9187911.html

时间: 2024-11-10 19:46:30

管理信息系统第二学期课程设计的相关文章

第二次课程设计实验

2019春第二次课程设计实验报告 一. 实验项目名称 贪吃蛇游戏 二. 实验项目功能描述 一个能由用户手动输入实现的用户操控一串字符数组移动达成相应条件改变字符数组的贪吃蛇游戏 三. 项目模块结构介绍 四. 实现界面展示 五. 代码托管链接 https://gitee.com/llf1202/flappy-1/blob/master/tcs.cpp 六. 实验总结 问题:游戏运行时,出现sleep(2000)函数没有定义 解决:开始我是怀疑我的代码打错了,某个函数打错了,反复对照书上的代码还是没

第二次课程设计实验报告

2019春第二次课程设计实验报告 一.实验项目名称 贪吃蛇小游戏 二.实验项目功能描述 玩家通过键盘控制蛇在地图上寻找食物,蛇吃下食物,可以加分,碰到四壁或者自己游戏结束. 三.项目模块结构介绍 程序关键在于表示蛇的图形及蛇的移动.用一个小圆点来表示蛇的一节身体,身体每长一节,增加一个圆点,蛇头用四节来表示.移动时必须从蛇头开始,所以蛇不能向相反的大反向移动,如果不按任意键,蛇自行在当前方向上前移,如果按与蛇方向相反的方向键,此游戏就会暂停,再按向前的方向键才能继续游戏,但按下有效方向键后,蛇头

20162328蔡文琛 第二学期课程总结

学号20162328 2016-2017-2<程序设计与数据结构>课程总结 每周作业链接汇总 第一周作业 算法+程序机构=程序 渐进复杂度称为算法的阶. 算法分析是计算机科学的基础课题 第三周作业 查找是在一组项内找到指定目标或是确定目标不存在的过程. 搞高效的查找使得比较的次数最少. Comparable接口允许许多动态实现算法,而不是指应用于特定的类. 二分查找的每次比较都排除了一半的可行候选数据. 排序是按某种标准将一列数据项按确定的次序重排的过程. 教材学习内容总结 教材学习中的问题和

20162309《程序设计与数据结构》第二学期课程总结

每周作业链接汇总 1.http://www.cnblogs.com/Metwox/p/7501901.html第一周作业,简要内容:学习基本的算法分析,了解算法复杂度的基本内容. 2.http://www.cnblogs.com/Metwox/p/7536289.html第二周作业,简要内容:教材第13章内容,学习排序和查找,了解几种查找方式的区别和联系. 3.http://www.cnblogs.com/Metwox/p/7580933.html第三周作业,简要内容:学习排序和查找的相关内容,

Java2019年第二学期课程总结

期末课程总结 本学期我们大致的学期了Java一些面向对象的开发,比如:多态性.JavaIO.图形界面开发等内容.这门课程和我们上学期学的C有很大的不同,但是一些基础的语法语句还是可以通用的. 一.Java基础程序设计 1.认识Java Java是一门编程语言,由于Java使用了大多数开发者较为习惯的编程模式,以及自身结构的良好设计,是的Java成为世界上最炙手可热的编程语言. 2.简单的Java程序 3.运算符 4.程序的结构 二.Java面对对象程序设计 1.类 2.封装 3.继承 4.多态

2019春年第二次课程设计实验报告

一.实验项目名称 反弹球消砖块 二.实验项目功能描述(用自己的语言描述) 控制挡板左右移动使飞行的小球消除砖块 三.项目模块结构介绍(文字+总体模型) 首先有个大致的框架,然后再根据自己的设计思路进行添加和删补,在上次的游戏中添加绘图 四.实现界面展示 五.代码托管链接 代码托管链接 六.实验总结(提出问题+解决办法+感想) 解决:通过搜索#include <graphics.h>,了解到这个头函数是在另外一个编译器上才能显示图案的,然后百度了Visual C++和Visual studio这

2019春第二次课程设计实验报告

一.实验项目名称 贪吃蛇 二.实验项目功能描述 这个项目主要是实现的蛇通过吃食物来增加长度,主要是通过'w','s'.'a'.'d'来控制蛇的上下左右移动,蛇在限制空间活动,食物随机出现,通过吃食物来增加长度,每吃一个食物长度增加一节,如果蛇碰到边界则游戏结束. 三.项目模块结构介绍 主要就是通过不停的循环主函数里的几个自定义函数去实现游戏,主要分为数据的初始化函数(startup()).显示画面的函数(show()).与用户输入无关的数据更新的一个函数(updatewithoutInput()

2019 春第二次课程设计实验报告

一.实验项目名称 贪吃蛇 二.实验项目功能描述(用自己的语言描述) 本实验通过我们自己制作小时候玩的贪吃蛇经典游戏,来提升自己的实践能力. 三.项目模块结构介绍(文字+总体模型) 模块1:构造一条静止的小蛇 模块2:实现小蛇的移动 模块3:用asdw键控制小蛇的移动 模块4:判断小蛇和边框或自身相撞时游戏失败 模块5:吃食物一个长度 四.实现界面展示(截图) 五.代码托管链接 https://gitee.com/TiAmo0520/events 六.实验总结(提出问题+解决办法+感想) 提问:如

asp.net,java,jsp,安卓Android,苹果ios,php,vb.net,c#免费毕业课程设计源码共享网盘下载

百度网盘下载地址1:  http://pan.baidu.com/s/1o67fybC 百度网盘下载地址2: http://pan.baidu.com/s/1kTxckmF163网盘下载地址:http://home.163disk.com/shuangyulin file://E:\计算机设计参考!!!!!!!!!!!\资料 (4 folders, 0 files, 0 bytes, 641.25 MB in total.) ├─QQ254540457 (0 folders, 49 files,