团队作业4——项目冲刺【Alpha阶段】第二次 Scrum Meeting


【Alpha阶段】第二次Scrum Meeting

这个作业属于哪个课程 软件工程
这个作业要求在哪里 作业要求
这个作业的目标 站立式会议+项目燃尽图+成员代码/文档签入记录+每人每日总结

Github仓库链接

团队队员

学号 姓名
3119005415 黄奕威
3219005447 连婉玲
3119005417 黄智权
3119005431 欧智昕
3219005448 刘淑婷
3119005410 冯波昌
3219005445 何婉莹

一、例会图片

lihui1.jpg

二、Burndown Chart

r1.png


三、代码/文档签入记录

z1.png

z2.png

z3.png

z4.png


四、项目进度

队员 昨日已完成任务 任务概述 今日待完成任务
黄奕威 时间安排表 · Issue #1、总结 · Issue #2 完成项目时间安排表;完成主界面、用户界面、关卡界面的UI搭建 动画完善、UI完善、后台通讯尝试
连婉玲 总结 · Issue #6 完成了用户类的初始设计 完善用户类
黄智权 总结 · Issue #7 完成精灵类的总体设计 精灵升级策略、精灵技能策略实现;数据库精灵表、技能表的初始化
欧智昕 总结· Issue #5 完成了精灵类的基本设计 继续根据需求完善精灵类
刘淑婷 总结 · Issue #3 完成了后台框架的搭建 尝试与前端进行接口对接
冯波昌 总结 · Issue #4 完成道具类的初始设计 继续完善道具类
何婉莹 总结 · Issue #8 查看接口文档,初步规划接口 尝试与前端进行接口对接

五、最新模块代码

日志信息配置(点击查看)
<?xml version="1.0" encoding="UTF-8"?>



    

    
    
        
        

        
        
        
        
    

    

        
            
            
            
            
        

        
        
            
        

        
        
            
            
            
            
                
                
                
            
            
            
        

        
        
            
            
            
            
                
                
                
            
            
            
        

        
        
            
            
            
            
                
                
                
            
            
            
        

    

    
    
    

        
        
            
        
        
        
        
            
        

        
            
            
            
            
            
        
    


UI(点击查看)
// 冒险页面
export default class Adventure extends Component {
  render () {
    return (
      
{adventure.map(item => ( ))}
) } } // 主页模块 function Home () { let [isClick, setClick] = useState(false) if (isClick) { return (
@信安1班——红橙黄绿青蓝紫队
) } else { return (
@信安1班——红橙黄绿青蓝紫队
) } }
用户类初步实现(点击查看)
public class User {
    private int id;
    private int progress; //进度
    private String user_name;
    private String password;
    private String email;
    private ArrayList spirits_bag; //精灵背包
    private ArrayList props_bag; //道具背包
}
项目框架搭建(点击查看)
public class WebLogAspect {
    private static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    @Pointcut("@annotation(ruangong.our_land.aspect.WebLog)")
    public void doWebLog(){
    }

    @Before("doWebLog()")
    public void before(JoinPoint joinPoint) throws ClassNotFoundException {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //注解描述信息
        String description = getAspectLogDescription(joinPoint);
        logger.info("====================start=================");
        logger.info("URL         :{}",request.getRequestURL().toString());
        logger.info("Description             :{}",description);
        logger.info("HTTP Method    :{}",request.getMethod());
        logger.info("Class Method  :{}.{}",joinPoint.getSignature().getDeclaringTypeName(),joinPoint.getSignature().getName());
        logger.info("IP    :{}",request.getRemoteAddr());
        logger.info("Request Arags:    {}",new Gson().toJson(joinPoint.getArgs()));
    }

    @After("doWebLog()")
    public void after(){
        logger.info("===============end====================");
    }

    @Around("doWebLog()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object result = proceedingJoinPoint.proceed();
        return result;
    }

    public String getAspectLogDescription(JoinPoint joinPoint) throws ClassNotFoundException {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        Class<?> target = Class.forName(targetName);
        Method[] methods = target.getMethods();
        StringBuilder builder = new StringBuilder();
        for (Method method:methods){
            if (method.getName().equals(methodName)){
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length==args.length){
                    builder.append(method.getAnnotation(WebLog.class).message());
                    break;
                }
            }
        }
        return builder.toString();
    }

    @AfterReturning(pointcut = "doWebLog()",returning = "result")
    public void afterReturning(JoinPoint joinPoint,Object result){
        logger.info("Response Args:      {}",new Gson().toJson(result));
    }

    @AfterThrowing(pointcut = "doWebLog()",throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint,Exception exception){
        logger.info("Exception e:      {}",exception.getMessage());
    }
}
精灵类实现(点击查看)
package ruangong.our_land.model.spirit;

import lombok.Data;
import lombok.Getter;
import org.springframework.lang.NonNull;
import ruangong.our_land.model.helper.ObjectHelper;
import ruangong.our_land.model.spirit.monster.Monster;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.util.HashMap;
import java.util.Map;

/**
 * 精灵类,包括boss、用户初始和野怪
 *
 * @author HuangZhiquan
 * @author Wizardk
 * @Description 精灵类
 * @date Created in 2021-11-02 22:57
 * @Modified By
 */
@Data
public abstract class Spirit {

    /**
     * 精灵的最高等级
     */
    @Max(value = 100, message = "等级最高为100")
    public static final int MAX_LEVEL = 100;

    /**
     * 精灵名
     */
    @NonNull
    @Getter
    private final String name;

    /**
     * 精灵的id
     */
    @NonNull
    @Getter
    private final String id;

    /**
     * 精灵是否稀有(是:1,否:0)
     * 精灵稀有与否,关系到精灵捕捉时的成功率
     */
    @NonNull
    @Getter
    private int isRare;

    /**
     * 等级
     */
    @Getter
    @Min(value = 1, message = "等级最低为1")
    private int level;
    /**
     * 血量
     */
    @Getter
    @Min(value = 0)
    private int blood;
    /**
     * 攻击力
     */
    @Getter
    @Min(value = 0)
    private static int attack;
    /**
     * 防御力
     */
    @Getter
    @Min(value = 0)
    private static int defence;
    /**
     * 速度
     */
    @Getter
    @Min(value = 0)
    private static int speed;

    /**
     * 精灵类型(初始、野怪或boss)
     */
    private String type;

    /**
     * 精灵属性(水、火、草)
     */
    private String nature;

    /**
     * 存放精灵的4个技能
     */
    @NonNull
    private Map skillMap;

    //构造方法
    public Spirit(String name, String id, int level, int blood, int attack,
                  int defense, int speed,String type,String nature,int isRare) {
        this.name = name;
        this.id = id;
        this.level = level;
        this.blood = blood;
        this.attack = attack;
        this.defence = defense;
        this.speed = speed;
        this.type = type;
        this.nature = nature;
        this.isRare = isRare;
        setSkills();
    }

    private void setSkills() {
        if (skillMap == null) {
            Skill[] skills = ObjectHelper.requireNonNull(initSkills());
            this.skillMap = new HashMap<>(4);
            for (Skill skill : skills) {
                skillMap.put(skill.name, skill);
            }
        }
    }

    /**
     * 初始化技能
     * @return 返回技能列表
     */
    protected abstract Skill[] initSkills();

    /**
     * 根据技能名获取相应技能
     *
     * @param skillName 技能名
     * @return 返回对应的技能类对象
     */
    public Skill getSkills(String skillName) {
        String skill = ObjectHelper.requireNonNull(skillName, "skillName");
        if (skillMap == null) {
            return null;
        }
        if (!skillMap.containsKey(skill)) {
            throw new IllegalArgumentException("The skill \" " + skill + " \" not found! Please recheck!");
        }
        return skillMap.get(skill);
    }


    /**
     * 升级,使level+1
     */
    protected void levelUp() {
        if (this instanceof Monster && this.level < MAX_LEVEL) {
            this.level++;
        }
    }

    public void setBlood(int blood) {
        this.blood = ObjectHelper.verifyNonZeroPositive(blood, "blood");
    }

    public void setAttack(int attack) {
        this.attack = ObjectHelper.verifyNonZeroPositive(attack, "attack");
    }

    public void setDefence(int defense) {
        this.defence = ObjectHelper.verifyNonZeroPositive(defense, "defense");
    }

    public void setSpeed(int speed) {
        this.speed = ObjectHelper.verifyNonZeroPositive(speed, "speed");
    }

    /**
     * 技能类
     */
    @Data
    public static class Skill {
        //技能基本属性
        /**
         * 技能名
         */
        @NonNull
        @Getter
        String name;
        /**
         * 技能描述
         */
        @NonNull
        @Getter
        String description;
        /**
         * 技能使用次数
         */
        @Getter
        int times = 0;

        /**
         * 技能类型(伤害型或提升型)
         * 伤害型:基础伤害值
         * 提升型:提升精灵属性(攻击、防御、速度)
         */
        @NonNull
        @Getter
        String type;

        /**
         * 技能伤害(若技能为伤害型),用于精灵对战
         */
        @Getter
        int hurt;

        //提升型技能的构造方法
        public Skill(String name, String descrp,String type) {
            this.name = ObjectHelper.requireNonNull(name, "name");
            this.description = ObjectHelper.requireNonNull(descrp, "descrp");
            this.type = ObjectHelper.requireNonNull(type, "type");
        }

        //伤害型技能的构造方法
        public Skill(String name, String descrp,String type,int hurt) {
            this.name = ObjectHelper.requireNonNull(name, "name");
            this.description = ObjectHelper.requireNonNull(descrp, "descrp");
            this.type = ObjectHelper.requireNonNull(type, "type");
            this.hurt = hurt;
        }

        /**
         * 技能效果:
         * 伤害型:更新技能伤害值(用于对战)
         * 提升型:更新精灵属性(仅限于对战)
         */
        public void skillEffect(){
            if(this.type.equals("伤害型")){
                //当前伤害值 = 伤害值 * 攻击力
                this.hurt = this.hurt * attack;
            }else if(this.type.equals("提升型")){
                //通过判断技能描述,来判断是提升攻击力、防御力还是速度
                //开始为简单起见,假设属性提升按+1的方式提升
                if(this.description.contains("攻击力")){
                    attack = attack + 1;
                }else if(this.description.contains("防御力")){
                    defence = defence + 1;
                }else if(this.description.contains("速度")){
                    speed = speed + 1;
                }
            }
        }

        public void setTimes(int times) {
            this.times = ObjectHelper.verifyNonZeroPositive(times, "times");
        }
    }
}

六、遇到的困难

  1. UI逻辑较为复杂,精灵对战动画效果实现不佳,需进一步完善。

  2. 精灵类中关于精灵升级策略、属性提升策略、精灵类继承问题有待解决。

  3. 接口逻辑还需进一步理清。

  4. 以矩阵形式随机生成野怪地图较难。


七、每人每日总结

黄奕威:UI逻辑较为复杂,精灵对战动画效果实现不佳,需进一步完善。

连婉玲:大家首次合作,配合得尚且不佳,后续需要更多的沟通与交流,以提升之后的任务完成效率。

黄智权:精灵类中关于精灵升级策略、属性提升策略、精灵类继承问题有待解决。

欧智昕:时间管理尤为重要,根据各成员的分工与实际能力,客观分析预计完成时间,合理评估各自的执行力与任务完成效率,以便对各模块进行灵活的人员调整。

刘淑婷:敏捷开发需要定期集结各位成员进行项目进程的商讨,各抒己见、集思广益,充分有效的沟通十分重要,各成员的分工需明确且清晰,讨论确定当日计划,并动手付诸实践。

冯波昌:只要思想不滑坡,办法总比困难多。要沉得住气,静得下心去思考问题,一个人的半途而废会严重影响整个团队的进程。

何婉莹:在代码实现的过程中,难免会遇到自己难以解决的实质性难题,寻求队友的帮助不失为一种好方法。相互交换思考过程,有助于彼此逻辑能力的提升。

相关