[Canvas]首个小游戏告成
英雄在地图上射箭杀怪兽,杀完了就胜利了。
点此下载程序试玩。
图例:


代码:
<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head>
     <title>地图加载 英雄可以射箭了 19.3.6 15:37 by:逆火狂飙 horn19782016@163.com</title>
     <style>
     #canvas{
        background:#ffffff;
        cursor:pointer;
        margin-left:10px;
        margin-top:10px;
        -webkit-box-shadow:3px 3px 6px rgba(0,0,0,0.5);
        -moz-box-shadow:3px 3px 6px rgba(0,0,0,0.5);
        box-shadow:3px 3px 6px rgba(0,0,0,0.5);
     }
     #controls{
        margin-top:10px;
        margin-left:15px;
     }
     </style>
    </head>
     <body onload="init()">
        <div id="controls">
            <input id='animateBtn' type='button' value='开始'/>
        </div>
        <canvas id="canvas" width="160px" height="160px" >
            出现文字表示你的浏览器不支持HTML5
        </canvas>
     </body>
</html>
<script type="text/javascript">
<!--
var paused=true;
animateBtn.onclick=function(e){
    paused=! paused;
    if(paused){
        animateBtn.value="开始";    
    }else{
        animateBtn.value="停止";
        window.requestAnimationFrame(animate);
    }
}
var ctx;// 绘图环境
var r;// 表盘半径
var terrain;
var hero;
var arrows;
function init(){
    // init Canvas
    var canvas=document.getElementById('canvas');
    r=160;
    canvas.width =2*r;
    canvas.height=2*r;
    ctx=canvas.getContext('2d');
    terrain=new Terrain();
    hero=new Hero();
    arrows=new Array();
    // 响应键盘事件
    canvas.addEventListener('keydown', doKeyDown, true);
    canvas.focus();
    window.addEventListener('keydown', doKeyDown, true);
};
function draw(){
    // Clear Canvas
    ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
    ctx.fillStyle="#ECF5FF";
    ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);
    terrain.paint(ctx);
    hero.paint(ctx);
    console.log('draw arrows.length='+arrows.length);
    for(var i=arrows.length-1;i>-1;i--){
        var arrow=arrows[i];
        var x=parseInt(arrow.x / 32,10);
        var y=parseInt(arrow.y / 32,10);
        console.log(x+','+y);
        if(terrain.getValue(x,y)==3){
            terrain.setValue(x,y,0);
            arrows.splice(i,1);
            break;
        }
        if(terrain.getValue(x,y)!=0){
            arrows.splice(i,1);
        }
    }
    for(var i=0;i<arrows.length;i++){
        var arrow=arrows[i];
        arrow.paint(ctx);
    }
    if(terrain.hasMonster()==false){
        alert("You win");
        init();
    }
}
function animate(){
    if(!paused){
        draw();
        window.requestAnimationFrame(animate); /// 让浏览器自行决定帧速率
    }
}
function doKeyDown(e) {
    var keyID = e.keyCode ? e.keyCode :e.which;
    if(keyID === 38 || keyID === 87)  { // up arrow and W
        hero.move('up');
        e.preventDefault();
    }
    if(keyID === 39 || keyID === 68)  { // right arrow and D
        hero.move('right');
        e.preventDefault();
    }
    if(keyID === 40 || keyID === 83)  { // down arrow and S
        hero.move('down');
        e.preventDefault();
    }
    if(keyID === 37 || keyID === 65)  { // left arrow and A
        hero.move('left');
        e.preventDefault();
    }
    //alert('keyID='+keyID);
    if(keyID === 32 )  { // SpaceBar
        //alert(1);
        var a=new Arrow(hero.x+16,hero.y+16,hero.direction);
        arrows.push(a);
        console.log('arrows.length='+arrows.length);
        e.preventDefault();
    }
}
//---------------------------------------------------地形类定义开始------------------------------------------------------------------->>
Terrain=function(){
    this.files=["road.png","tree.png","home.png","skull.png",];
    this.maps=new Array(
        [0,0,0,0,0,3,0,0,0,0],
        [0,0,1,1,1,1,1,1,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,2,2,2,2,2,2,2,0],
        [0,3,0,0,0,0,2,0,0,0],
        [0,0,0,2,0,0,2,0,0,3],
        [0,0,0,2,0,0,0,0,0,0],
        [0,2,2,2,2,2,2,2,0,0],
        [0,0,3,0,0,0,0,0,0,0],
        [0,1,1,1,1,1,1,1,1,0],
    );
}
Terrain.prototype={
    files:[],
    // Property
    maps:0,
    // method
    paint:function(ctx){
        for(var i=0;i<this.maps.length;i++){
            var arr=this.maps[i];
            for(var j=0;j<arr.length;j++){
                var value=arr[j];
                var img=new Image();
                img.src=this.files[value];
                ctx.drawImage(img,i*32,j*32);
            }
        }
    },
    hasMonster:function(){
        for(var i=0;i<this.maps.length;i++){
            var arr=this.maps[i];
            for(var j=0;j<arr.length;j++){
                var value=arr[j];
                if(value==3){
                    return true;
                }
            }
        }
        return false;
    },
    getValue:function(i,j){
        if(i<0 || i>=this.maps.length){
            return undefined;
        }
        var arr=this.maps[i];
        if(j<0 || j>=arr.length){
            return undefined;
        }
        var value=arr[j];
        return value;
    },
    setValue:function(i,j,value){
        if(i<0 || i>=this.maps.length){
            return undefined;
        }
        var arr=this.maps[i];
        if(j<0 || j>=arr.length){
            return undefined;
        }
        arr[j]=value;
    },
}
//---------------------------------------------------地形类定义结束-------------------------------------------------------------------<<
//---------------------------------------------------英雄类定义开始------------------------------------------------------------------->>
Hero=function(){
    this.files=["arrow_left.png","arrow_right.png","arrow_up.png","arrow_down.png",];
    this.pngs=[
        {left:0,top:10,width:40,height:40},
        {left:0,top:66,width:40,height:40},
        {left:0,top:120,width:40,height:40},
        {left:0,top:180,width:40,height:40},
    ];
}
Hero.prototype={
    files:[],
    pngs:[],
    x:160,
    y:160,
    xTo:160,
    yTo:160,
    step:32,
    direction:'up',
    // method
    paint:function(ctx){
        var img=new Image();
        img.src='bowman.png';
        var index=0;
        if(this.direction=='up'){
            index=3;
        }
        if(this.direction=='down'){
            index=0;
        }
        if(this.direction=='left'){
            index=1;
        }
        if(this.direction=='right'){
            index=2;
        }
        var pos=this.pngs[index];
        ctx.drawImage(img,pos.left,pos.top,pos.width,pos.height,this.x,this.y,pos.width,pos.height);
        //ctx.drawImage(img,this.x,this.y);
    },
    move:function(direction){
        this.direction=direction;
        if(this.direction=='up'){
            this.yTo-=this.step;
        }
        if(this.direction=='down'){
            this.yTo+=this.step;
        }
        if(this.direction=='left'){
            this.xTo-=this.step;
        }
        if(this.direction=='right'){
            this.xTo+=this.step;
        }
        if(terrain.getValue(this.xTo/this.step,this.yTo/this.step)==0){
            this.x=this.xTo;
            this.y=this.yTo;
        }else{
            this.xTo=this.x;
            this.yTo=this.y;
        }
    }
}
//---------------------------------------------------英雄类定义结束-------------------------------------------------------------------<<
//---------------------------------------------------箭矢类定义开始------------------------------------------------------------------->>
Arrow=function(x,y,direction){
    this.x=x;
    this.y=y;
    this.direction=direction;
}
Arrow.prototype={
    x:0,
    y:0,
    velocity:1,// 飞行速度
    len:16,// 箭杆长
    direction:'',
    // method
    paint:function(ctx){
        var x1=this.x,y1=this.y;
        if(this.direction=='up'){
            this.y-=this.velocity;
            y1=this.y-this.len;
            x1=this.x;
        }
        if(this.direction=='down'){
            this.y+=this.velocity;
            y1=this.y+this.len;
            x1=this.x;
        }
        if(this.direction=='left'){
            this.x-=this.velocity;
            x1=this.x-this.len;
            y1=this.y;
        }
        if(this.direction=='right'){
            this.x+=this.velocity;
            x1=this.x+this.len;
            y1=this.y;
        }
        //alert("this.x="+this.x);
        //alert("this.y="+this.y);
        //alert("x1="+x1);
        //alert("y1="+y1);
        ctx.beginPath();
        ctx.lineWidth = 2;
        ctx.strokeStyle = "#ff0000";
        ctx.moveTo(this.x,this.y);
        ctx.lineTo(x1,y1);
        ctx.stroke();
        ctx.closePath();
        //alert(2);
    },
}
//---------------------------------------------------箭矢类定义结束-------------------------------------------------------------------<<
//-->
</script>
2019年3月6日18点06分
[Canvas]首个小游戏告成的更多相关文章
- java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏
		画笔Graphics Java中提供了Graphics类,他是一个抽象的画笔,可以在Canvas组件(画布)上绘制丰富多彩的几何图和位图. Graphics常用的画图方法如下: drawLine(): ... 
- Canvas进阶——制作小游戏【贪吃蛇】
		今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接PO代码,所以只copy代码的童鞋们请出门左转不谢. 按理说canvas与其应用是老生常谈了,可我在准备阶段却搜索不 ... 
- canvas 实现赛车小游戏
		一:样式 <style> #btn{ width: 60px; height: 30px; line-height: 30px; background: #7EC0EE; border: ... 
- canvas 实现微信小游戏
		var canvas = document.getElementById('canvas'); var cxt = canvas.getContext('2d'); var timer; var iS ... 
- 【JavaScript】canvas实现一个小游戏
		参考: 1.image onload事件:http://www.runoob.com/jsref/event-img-onload.html(赞) 2.canvas的drawImage无法显示图像:h ... 
- vs2019将小游戏打包成msi踩的坑(个人)
		1.VS无Setup projecrt? vs2015之前是自带打包msi功能的,vs2017之后需要自己去下载插件: 下载地址:https://marketplace.visualstudio.co ... 
- canvas drag 实现拖拽拼图小游戏
		博主一直心心念念想做一个小游戏- 前端时间终于做了一个小游戏,直到现在才来总结,哈哈- 以后要勤奋点更新博客! 实现原理 1.如何切图? 用之前的方法就是使用photoshop将图片切成相应大小的图 ... 
- 两个Canvas小游戏
		或许连小游戏都算不上,可以叫做mini游戏. 没有任何框架或者稍微有点深度的东西,所以有js基础的或者要追求炫酷效果的可以直接ctrl+w了. 先贴出两个游戏的试玩地址: 是男人就走30步 是男人就忍 ... 
- Vue+WebSocket+ES6+Canvas 制作「你画我猜」小游戏
		Vue+WebSocket+ES6+Canvas 制作「你画我猜」小游戏 转载 来源:jrainlau 链接:https://segmentfault.com/a/1190000005804860 项 ... 
随机推荐
- perl解析xml-XML::Simple/XMLin
			转自: http://blog.charlee.li/perl-xml-simple/ [Perl]用XML::Simple解析XML文件 在Perl中解析XML的方法最常见的就是使用 XML::DO ... 
- linux 内核crash 命令
			https://www.dedoimedo.com/computers/crash-book.html#download 
- 最近5年183个Java面试问题列表及答案[最全]
			Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别(String 类型和 StringBuffer 类型的主要性能区别其实在于 Stri ... 
- The main reborn ASP.NET MVC4.0: using CheckBoxListHelper and RadioBoxListHelper
			The new Helpers folder in the project, to create the CheckBoxListHelper and RadioBoxListHelper class ... 
- ASP.NET Web API中实现版本的几种方式
			在ASP.NET Web API中,当我们的API发生改变,就涉及到版本问题了.如何实现API的版本呢? 1.通过路由设置版本 最简单的一种方式是通过路由设置,不同的路由,不同的版本,不同的contr ... 
- 【python】python安装步骤
			1.官网下载python 官网地址:https://www.python.org/getit/ 2.下载完成后点击安装 勾选Add python to PATH 是可以自己去配置环境变量的 注意:这里 ... 
- Android按返回键退出程序但不销毁,程序后台运行,同QQ退出处理方式
			@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BA ... 
- 异步图片下载引擎(升级版——ExecutorService+handler)
			[Android分享] 异步图片下载引擎(升级版——ExecutorService+handler) [复制链接] 皮诺 13 主题 5 好友 844 积分 No.4 中级开发者 升级 2 ... 
- Linux网络之设备接口层:发送数据包流程dev_queue_xmit
			转自:http://blog.csdn.net/wdscq1234/article/details/51926808 写在前面 本文主要是分析kernel-3.8的源代码,主要集中在Network的n ... 
- Swift - 用CATransform3DMakeRotation实现翻页效果
			Swift - 用CATransform3DMakeRotation实现翻页效果 效果 源码 https://github.com/YouXianMing/Swift-Animations // // ... 
