zoukankan      html  css  js  c++  java
  • 通过游戏学javascript系列第一节Canvas游戏开发基础

    本节教程通过一个简单的游戏小例子,讲解Canvas的基础知识。

    最终效果:

    点击移动的方块,方块上的分数会增加,方块的行进方向会改变,并且方块的速度会增加。

    在线演示

    源码

    HTML5引入了canvas元素。canvas元素为我们提供了一块空白画布。我们可以使用此画布来绘制和绘制我们想要的任何东西。JavaScript为我们提供了动态制作动画并绘制到画布上所需的工具。它不仅提供绘图和动画系统,还可以处理用户交互。在本教程中,我们将使用纯JavaScript制作基本的HTML5 Canvas框架,该框架可用于制作真实的游戏。在本教程的结尾创建了一个非常简单的游戏,以演示HTML5 Canvas与JavaScript结合的优势。

    HTML5 Canvas基本游戏框架

    让我们围绕canvas元素创建一个基本的游戏框架。我们需要一个HTML5文件和一个JavaScript文件。HTML5文件应包含canvas元素和对JavaScript文件的引用。JavaScript文件包含将代码绘制到canvas元素的代码。

    这是HTML5文件index.html:

    <head>
    <meta charset="UTF-8">
    <title>Canvas Example</title>
    <script type="text/javascript" src="framework.js"></script>
    </head>
    <body>
    <canvas id="viewport" width="640" height="480"></canvas>
    </body>
    </html> 
    

    如您所见,JavaScript文件game.js包含在html文件的头部。画布元素以名称“ viewport”定义,其宽度为640像素,高度为480像素。在我们的framework.js中,我们需要使用其名称查找canvas元素,以便可以在其上进行绘制。我们正在创建的框架应支持渲染循环以及玩家与鼠标的交互。对于渲染循环,我们将使用Window.requestAnimationFrame()。通过添加鼠标事件侦听器来启用鼠标交互。

    这是JavaScript文件framework.js:

    // The function gets called when the window is fully loaded
    window.onload = function() {
        // Get the canvas and context
        var canvas = document.getElementById("viewport"); 
        var context = canvas.getContext("2d");
    
        // Timing and frames per second
        var lastframe = 0;
        var fpstime = 0;
        var framecount = 0;
        var fps = 0;
        
        // Initialize the game
        function init() {
            // Add mouse events
            canvas.addEventListener("mousemove", onMouseMove);
            canvas.addEventListener("mousedown", onMouseDown);
            canvas.addEventListener("mouseup", onMouseUp);
            canvas.addEventListener("mouseout", onMouseOut);
        
            // Enter main loop
            main(0);
        }
        
        // Main loop
        function main(tframe) {
            // Request animation frames
            window.requestAnimationFrame(main);
            
            // Update and render the game
            update(tframe);
            render();
        }
        
        // Update the game state
        function update(tframe) {
            var dt = (tframe - lastframe) / 1000;
            lastframe = tframe;
            
            // Update the fps counter
            updateFps(dt);
        }
        
        function updateFps(dt) {
            if (fpstime > 0.25) {
                // Calculate fps
                fps = Math.round(framecount / fpstime);
                
                // Reset time and framecount
                fpstime = 0;
                framecount = 0;
            }
            
            // Increase time and framecount
            fpstime += dt;
            framecount++;
        }
        
        // Render the game
        function render() {
            // Draw the frame
            drawFrame();
        }
        
        // Draw a frame with a border
        function drawFrame() {
            // Draw background and a border
            context.fillStyle = "#d0d0d0";
            context.fillRect(0, 0, canvas.width, canvas.height);
            context.fillStyle = "#e8eaec";
            context.fillRect(1, 1, canvas.width-2, canvas.height-2);
            
            // Draw header
            context.fillStyle = "#303030";
            context.fillRect(0, 0, canvas.width, 65);
            
            // Draw title
            context.fillStyle = "#ffffff";
            context.font = "24px Verdana";
            context.fillText("HTML5 Canvas Basic Framework ", 10, 30);
            
            // Display fps
            context.fillStyle = "#ffffff";
            context.font = "12px Verdana";
            context.fillText("Fps: " + fps, 13, 50);
        }
        
        // Mouse event handlers
        function onMouseMove(e) {}
        function onMouseDown(e) {}
        function onMouseUp(e) {}
        function onMouseOut(e) {}
        
        // Get the mouse position
        function getMousePos(canvas, e) {
            var rect = canvas.getBoundingClientRect();
    
            return {
                x: Math.round((e.clientX - rect.left)/(rect.right - rect.left)*canvas.width),
                y: Math.round((e.clientY - rect.top)/(rect.bottom - rect.top)*canvas.height)
            };
        }
        
        // Call init to start the game
        init();
    };
    

    上面的代码绘制了一个带有边框,标题和每秒帧数的简单框架。这是代码生成的内容

    带有弹跳方块的游戏

    现在我们有了一个框架,让我们用它创建一个简单的游戏。我们将创建一个在屏幕上具有反弹方块的游戏。当玩家单击它时,方块上的分数会增加,方块的行进方向会改变,并且方块的速度会增加。

    首先,我们定义一些对象和属性。该级别定义了方块可以反弹的区域。方块本身具有位置,尺寸和运动属性。最后,有一个分数。

        // Level properties
        var level = {
            x: 1,
            y: 65,
             canvas.width - 2,
            height: canvas.height - 66
        };
     
        // Square
        var square = {
            x: 0,
            y: 0,
             0,
            height: 0,
            xdir: 0,
            ydir: 0,
            speed: 0
        }
     
        // Score
        var score = 0;
    

    我们需要在init()函数中初始化对象和属性。

        // Initialize the game
        function init() {
            // Add mouse events
            canvas.addEventListener("mousemove", onMouseMove);
            canvas.addEventListener("mousedown", onMouseDown);
            canvas.addEventListener("mouseup", onMouseUp);
            canvas.addEventListener("mouseout", onMouseOut);
     
            // Initialize the square
            square.width = 100;
            square.height = 100;
            square.x = level.x + (level.width - square.width) / 2;
            square.y = level.y + (level.height - square.height) / 2;
            square.xdir = 1;
            square.ydir = 1;
            square.speed = 200;
     
            // Initialize the score
            score = 0;
     
            // Enter main loop
            main(0);
        }
    

    这些对象需要更新,因此让我们修改update()函数。方块需要移动,并且应该检测并解决与标高边缘的碰撞。

        // Update the game state
        function update(tframe) {
            var dt = (tframe - lastframe) / 1000;
            lastframe = tframe;
     
            // Update the fps counter
            updateFps(dt);
     
            // Move the square, time-based
            square.x += dt * square.speed * square.xdir;
            square.y += dt * square.speed * square.ydir;
     
            // Handle left and right collisions with the level
            if (square.x <= level.x) {
                // Left edge
                square.xdir = 1;
                square.x = level.x;
            } else if (square.x + square.width >= level.x + level.width) {
                // Right edge
                square.xdir = -1;
                square.x = level.x + level.width - square.width;
            }
     
            // Handle top and bottom collisions with the level
            if (square.y <= level.y) {
                // Top edge
                square.ydir = 1;
                square.y = level.y;
            } else if (square.y + square.height >= level.y + level.height) {
                // Bottom edge
                square.ydir = -1;
                square.y = level.y + level.height - square.height;
            }
        }
    

    我们需要绘制方块和分数。这需要在render()函数中完成。

        // Render the game
        function render() {
            // Draw the frame
            drawFrame();
     
            // Draw the square
            context.fillStyle = "#ff8080";
            context.fillRect(square.x, square.y, square.width, square.height);
     
            // Draw score inside the square
            context.fillStyle = "#ffffff";
            context.font = "38px Verdana";
            var textdim = context.measureText(score);
            context.fillText(score, square.x+(square.width-textdim.width)/2, square.y+65);
        }
    

    最后一步是添加鼠标交互。让我们将代码添加到onMouseDown()函数中。

       function onMouseDown(e) {
            // Get the mouse position
            var pos = getMousePos(canvas, e);
     
            // Check if we clicked the square
            if (pos.x >= square.x && pos.x < square.x + square.width &&
                pos.y >= square.y && pos.y < square.y + square.height) {
     
                // Increase the score
                score += 1;
     
                // Increase the speed of the square by 10 percent
                square.speed *= 1.1;
     
                // Give the square a random position
                square.x = Math.floor(Math.random()*(level.x+level.width-square.width));
                square.y = Math.floor(Math.random()*(level.y+level.height-square.height));
     
                // Give the square a random direction
                square.xdir = Math.floor(Math.random() * 2) * 2 - 1;
                square.ydir = Math.floor(Math.random() * 2) * 2 - 1;
            }
        }
    

    这是通过基本框架和一些修改而成的最终游戏。单击方块以增加您的分数并前进到下一个方块。

  • 相关阅读:
    php 信号量
    .net 反射初体验
    IEnumerable,IQueryable之前世今生
    [SQL]511+512+534+550+569
    [SQL]183+184+185+196+197
    [SQL]3.26--175+176+177+178+180+181+182
    [剑指offer]10.斐波那契数列+青蛙跳台阶问题
    [剑指offer]14-1.剪绳子
    [剑指offer]62.圆圈中最后剩下的数字
    [剑指offer]52.两个链表的第一个公共节点
  • 原文地址:https://www.cnblogs.com/neuedu/p/javascript-game-canvas.html
Copyright © 2011-2022 走看看