Web学习笔记-中期项目(拳皇)

news2024/11/19 23:30:05

CONTENTS

    • 项目原理
    • 一、基础文件
    • 二、ac_game_object框架
    • 三、游戏地图与玩家模型的创建

项目原理

游戏中一个物体运动的原理是浏览器每秒钟刷新60次,每次我们单独计算这个物体新的位置,然后把他刷新出来,这样最终人眼看起来就是移动的效果。

对于二维的移动,我们一般抽象出某个点比如左上角的坐标 ( x , y ) (x,y) (x,y),并记下物体的宽高 w , h w,h w,h和沿 x , y x,y x,y方向的速度 v x , v y v_x,v_y vx,vy,加入物体在水平方向上匀速运动,那么位移就为: x = x 0 + v x t x=x_0+v_xt x=x0+vxt

一、基础文件

首先我们创建主界面index.html以及基础CSS、JS文件base.cssbase.js。然后设置好主界面的大小和背景(此时JS文件没有功能,只用于测试):

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>King of Fighters</title>

    <link rel="stylesheet" href="/static/css/base.css">
    <script src="/static/js/jquery-3.6.1.min.js"></script>
</head>

<body>
    <div id="kof"></div>

    <script type="module">
        import { KOF } from '/static/js/base.js';

        let kof = new KOF('kof');
    </script>
</body>

</html>
#kof {
    width: 1280px;
    height: 720px;

    background-image: url('/static/images/background/1.gif');
    background-size: 100% 100%;
    background-position: top;
}
class KOF {
    constructor(id) {
        this.$kof = $('#' + id);
        console.log(this.$kof);
    }
}

export {
    KOF
}

二、ac_game_object框架

项目中的背景、两个玩家一共三个元素,对于这三个元素我们都需要实现每秒钟刷新60次,所以我们可以让这三个元素继承至同一个元素,我们在/static/js中创建一个新的文件夹ac_game_object,并在该文件夹创建base.js(为了区分之后称为ac_game_object/base.js)。该文件框架代码如下:

let AC_GAME_OBJECTS = [];

class AcGameObject {
    constructor() {
        AC_GAME_OBJECTS.push(this);

        this.timedelta = 0;  // 存储当前这帧距离上一帧的时间间隔
        this.has_call_start = false;  // 表示当前对象是否执行过start()
    }

    start() {  // 初始化执行一次

    }

    update() {  // 除第一帧外每帧执行一次

    }

    destroy() {  // 删除当前对象
        for (let i in AC_GAME_OBJECTS) {
            if (AC_GAME_OBJECTS[i] === this) {
                AC_GAME_OBJECTS.splice(i, 1);
                break;
            }
        }
    }
}

let last_timestamp;  // 记录上一帧在什么时间执行

let AC_GAME_OBJECTS_FRAME = (timestamp) => {
    for (let obj of AC_GAME_OBJECTS) {
        if (!obj.has_call_start) {
            obj.start();
            obj.has_call_start = true;
        } else {
            obj.timedelta = timestamp - last_timestamp;
            obj.update();
        }
    }

    last_timestamp = timestamp;

    requestAnimationFrame(AC_GAME_OBJECTS_FRAME);
}

requestAnimationFrame(AC_GAME_OBJECTS_FRAME);

三、游戏地图与玩家模型的创建

使用canvas设计基本的地图和玩家,/static/js/game_map/base.js代码如下:

import { AcGameObject } from '/static/js/ac_game_object/base.js'

class GameMap extends AcGameObject {
    constructor(root) {
        super();

        this.root = root;
        this.$canvas = $('<canvas width="1280" height="720" tabindex=0></canvas>');
        this.ctx = this.$canvas[0].getContext('2d');
        this.root.$kof.append(this.$canvas);
        this.$canvas.focus();
    }

    start() {

    }

    update() {
        this.render();
    }

    render() {  // 渲染函数
        // 每一帧需要清空地图,不然看到的效果就不是物体在移动,而是拖出一条线
        this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
        this.ctx.fillStyle = 'black';
        this.ctx.fillRect(0, 0, this.$canvas.width(), this.$canvas.height());
    }
}

export {
    GameMap
}

/static/js/player/base.js代码如下:

import { AcGameObject } from "/static/js/ac_game_object/base.js";

class Player extends AcGameObject {
    constructor(root, info) {
        super();

        this.root = root;
        this.id = info.id;
        this.x = info.x;
        this.y = info.y;
        this.width = info.width;
        this.height = info.height;
        this.color = info.color;

        this.vx = 0;
        this.vy = 0;

        this.speedx = 400;  // 水平速度
        this.speedy = 1000;  // 跳起的初始速度

        this.ctx = this.root.game_map.ctx;
    }

    start() {

    }

    update() {
        this.render();
    }

    render() {
        this.ctx.fillStyle = this.color;
        this.ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

export {
    Player
}

主文件base.js代码如下:

import { GameMap } from '/static/js/game_map/base.js';
import { Player } from '/static/js/player/base.js';

class KOF {
    constructor(id) {
        this.$kof = $('#' + id);

        this.game_map = new GameMap(this);
        this.players = [
            new Player(this, {
                id: 0,
                x: 200,
                y: this.$kof.height() - 200,
                width: 120,
                height: 200,
                color: 'blue'
            }),
            new Player(this, {
                id: 1,
                x: 900,
                y: this.$kof.height() - 200,
                width: 120,
                height: 200,
                color: 'red'
            }),
        ]
    }
}

export {
    KOF
}

此时的效果如下图所示:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/10963.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLO系列概述(yolov1至yolov7)

YOLO系列概述&#xff08;yolov1至yolov7&#xff09; 参考&#xff1a; 睿智的目标检测53——Pytorch搭建YoloX目标检测平台YoloV7 yolo的发展历史 首先我们来看一下yolo系列的发展历史&#xff0c;yolo v1和yolox是anchor free的方法&#xff0c;yolov2&#xff0c;yolov3…

使用 Vue3 实现锚点组件

目录 1. 需求介绍 2. 实现过程 2.1 表单结构介绍 2.2 确定锚点组件接收的参数及使用方法 2.2.1 form-dom&#xff1a;需要被锚点组件控制的表单实例 2.2.2 active-anchor&#xff1a;默认激活的锚点 2.2.3 title-class&#xff1a;表单标题特有的类名 2.2.4 将 锚点组件…

5-FITC,5-FITC(isomer I),5-异硫氰酸荧光素,5-Flourescein iso-thiocyanate

产品名称&#xff1a;5-FITC&#xff0c;5-异硫氰酸荧光素 英文名称&#xff1a;5-Flourescein iso-thiocyanate 英文别名&#xff1a;5-FITC&#xff1b;5-Flourescein iso-thiocyanate&#xff1b;FITC Isomer I [5-FITC; fluorescein-5-isothiocyanate] CAS#&#xff1a;…

labview 串口通信 modbusRtu

在自动化或测试项目中&#xff0c;上位机软件需要和PLC及仪表通信&#xff0c;本文简单描述这个问题。 1.在程序框图中放置4个图标 &#xff08;1&#xff09;创建modbus 主站实例&#xff08;按如下图标识①,在框图中放Create Master Instance.vi) 图1 放置四个图标 &…

C++ Reference: Standard C++ Library reference: Containers: deque: deque: resize

C官网参考链接&#xff1a;https://cplusplus.com/reference/deque/deque/resize/ 公有成员函数 <deque> std::deque::resize C98 void resize (size_type n, value_type val value_type()); C11 void resize (size_type n); void resize (size_type n, const value_t…

React组件复用

mixins&#xff08;已废弃&#xff09; https://react.docschina.org/blog/2016/07/13/mixins-considered-harmful.html mixin引入了隐式依赖关系 对于组件中的方法和数据的来源不明确&#xff0c;不容易维护 Mixins 导致名称冲突Mixins 导致滚雪球般的复杂性 render-props技术…

C语言学习之路(基础篇)—— 指针(上)

说明&#xff1a;该篇博客是博主一字一码编写的&#xff0c;实属不易&#xff0c;请尊重原创&#xff0c;谢谢大家&#xff01; 概述 1) 内存 内存含义&#xff1a; 存储器&#xff1a; 计算机的组成中&#xff0c;用来存储程序和数据&#xff0c;辅助CPU进行运算处理的重要…

python切分TXT的句子到Excel(复制可用)——以及python切分句子遇到的问题汇总

文章目录完整代码时间转化和提取各种对象类型转换时间序列类属性数据转换完整代码 import jieba.analyseimport jieba.posseg as pseg from wordcloud import WordCloud import xlsxwriter # encodinggbk import xlsxwriterf open(E:/data/xieyangteng/review.txt, r, encodi…

波的相关参数概念整理

频率&#xff08;frequency&#xff09;&#xff0c;符号f&#xff0c;表示单位时间内完成周期性变化的次数。f1/T&#xff0c;单位s-1 角频率&#xff0c;符号ω&#xff0c;表示单位时间内变化的角弧度值。ω 2πf 2π/T,单位rad/s 波长&#xff08;wavelength&#xff0…

<SQL编程工具MySQL、SQLyog安装及环境配置教程>——《SQL》

目录 1.MySQL安装&#xff1a; 1.1 MySQL下载安装&#xff1a; 1.2 MySQL环境变量配置&#xff1a; 2.SQLyog安装&#xff1a; 2.1 SQLyog下载安装&#xff1a; 3.写在最后的话&#xff1a; 后记&#xff1a;●由于作者水平有限&#xff0c;文章难免存在谬误之处&…

力扣刷题day49|647回文子串、516最长回文子序列

文章目录647. 回文子串思路暴力解法动态规划五部曲516. 最长回文子序列思路动态规划五部曲647. 回文子串 力扣题目链接 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由…

代码随想录算法训练营第一天|LeetCode704二分查找、LeetCode27移除元素

LeetCode704二分查找 题目链接&#xff1a;704二分查找 思路&#xff1a; 以前刷过不少题&#xff0c;也看过不少题解&#xff0c;就记得区间有不少原则&#xff0c;乍一想有哪些想不起来了&#xff0c;反正我是选择了最简单易懂的左闭右闭原则。 1、区间左闭右闭原则。 2、w…

SpringBoot SpringBoot 开发实用篇 2 配置高级 2.3 常用计量单位应用

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇2 配置高级2.3 常用计量单位应用2.3.1 问题引入2.3.2 常用计量单位应…

实验2 存储器设计与实现【计算机组成原理】

实验2 存储器设计与实现【计算机组成原理】实验2 存储器设计与实现一、实验目的二、实验环境三、实验原理四、实验任务五、实验结果&#xff1a;六、心得体会&#xff1a;实验2 存储器设计与实现 一、实验目的 掌握单端口RAM和ROM原理和设计方法。掌握32位数据的读出和写入方…

【LeetCode-中等】343. 整数拆分(详解)

题目 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 力扣&#xff1a;题目链接 方法1&#xff1a;动态规划 完全不了解动态规划&#xff1f; 动态规划…

图像运算和图像增强九

图像运算和图像增强九 图像锐化之 Roberts、Prewitt 算子实现边缘检测 &#xff08;1&#xff09;图像锐化 图像锐化的目的是为了使图像的边缘、轮廓线以及图像的细节变得清晰&#xff0c;经过平滑的图像变得模糊的根本原因是图像受到了平均或积分运算&#xff0c;因此可以对…

LeetCode刷题(python版)——Topic70. 爬楼梯

一、题设 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2 阶 示例…

Flutter混编之路IOS插件0基础开发(mac环境)

本文默认你安装了Android Studio、Xcode具备flutter开发环境&#xff0c;并且会dart语言的基础使用&#xff0c;Android、ios原生开发不会也没啥关系&#xff0c;就是会很费劲啦。 1.创建插件 在Android studio 点击File-->new Flutter Project-->Flutter 取好名字&…

Web大学生网页作业成品:基于html制作中国科技发展网站设计题材【航天之路7页】HTML+CSS+JavaScript

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Celery快速使用(定时任务、Django中使用Celery、秒杀逻辑、双写一致性)

文章标题一、Celery快速使用二、Celery包结构三、Celery异步任务 延时任务 定时任务四、Django中使用Celery五、秒杀逻辑六、双写一致性1&#xff09;路飞项目接口加缓存2&#xff09;Celery定时任务实现双写一致性一、Celery快速使用 简单介绍Celery Celery官网:http://www.…