//html部分

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>贪吃蛇大作战</title>
<style type="text/css">
#gamepanel{
width: 320px;
margin: 0 auto;
height: 568px;
position: relative;
overflow: hidden;
border: 1px solid #ccc
}
body{
padding: 0;
margin: 0;
}
</style>
</head>
<body>

<div id="gamepanel">
<canvas id="canvas" width="320" height="568" >
当前浏览器不支持Canvas,请更换浏览器后再试
</canvas>
</div>
<script src="countdown.js"></script>
</body>
</html>

//js部分

window.onload=function(){
// window_width = 512
// window_height = 480

var canvas=document.getElementById('canvas');
var context=canvas.getContext('2d');

// 游戏对象
var snake = {
jiaodu: 180,
speed: 80, // 每秒移动的像素
x: (canvas.width / 2),
y: canvas.height / 2,
r: 10,
body: [
{
x: (canvas.width / 2),
y: canvas.height / 2,
}
],
snakeLength: 100

};

//地图对象
var ditu = {
w:canvas.width*3,
h:canvas.height*3,
canzhao: {
x: canvas.width*3/2,
y: canvas.height*3/2,
},
item:{
x:0,
y:0
},
snake:null,
arr: [
{
x: canvas.width / 2 +200,
y: canvas.height / 2 - 200,
color:"yellow"
},
{
x: canvas.width / 2 +200,
y: canvas.height / 2 +200,
color:"#ccc"
},
{
x: canvas.width / 2 -200,
y: canvas.height / 2 +200,
color:"blue"
},
{
x: canvas.width / 2 -200,
y: canvas.height / 2 - 200,
color:"#ccc"
}
]
}
// console.dir(ditu.w)

// 摇杆
var yaogan = {
kg:false,
jiaodu: 180,
r:60,
click: {
x:60+10,
y:canvas.height-110,
},
gan: {
x:60+10,
y:canvas.height-110,
r:20
},
dot: {
x:60+10,
y:canvas.height-110
}
}
// console.dir(yaogan.dot)

// 绑定事件
canvas.addEventListener('touchstart',touch,false);
canvas.addEventListener('touchmove',touch,false);
canvas.addEventListener('touchend',touch,false);

function touch (event){
var event = event || window.event
switch(event.type){
//按下屏幕
case "touchstart":
yaogan.kg = true;
yaogan.click.x = Math.round(event.touches[0].clientX);
yaogan.click.y = Math.round(event.touches[0].clientY);
break;
//离开屏幕
case "touchend":
yaogan.kg = false;
yaogan.click.x = yaogan.dot.x;
yaogan.click.y = yaogan.dot.y;
break;
// 触摸滑动
case "touchmove":
// 阻止冒泡
event.preventDefault();
yaogan.kg = true;
yaogan.click = {x:Math.round(event.touches[0].clientX),y:Math.round(event.touches[0].clientY)};
break;
}
}
var panduanjiaodu = function () {
var x = yaogan.click.x
var y = yaogan.click.y
if (x > yaogan.dot.x && y > yaogan.dot.y) {
//那么角度在0到90之间
yaogan.jiaodu = Math.floor((Math.atan((y-yaogan.dot.y)/(x-yaogan.dot.x))*180/Math.PI))
}
if (x < yaogan.dot.x && y > yaogan.dot.y) {
//那么角度在90到180之间
yaogan.jiaodu = Math.floor((Math.atan((yaogan.dot.x-x)/(y-yaogan.dot.y))*180/Math.PI))+90
}
if (x < yaogan.dot.x && y < yaogan.dot.y) {
//那么角度在180到270之间
yaogan.jiaodu = Math.floor((Math.atan((yaogan.dot.y-y)/(yaogan.dot.x-x))*180/Math.PI))+180
}
if (x > yaogan.dot.x && y < yaogan.dot.y) {
//那么角度在0到90之间
yaogan.jiaodu = Math.floor((Math.atan((yaogan.dot.x-x)/(y-yaogan.dot.y))*180/Math.PI))+270
}
}
var update = function (modifier) {
snake.body.length = snake.snakeLength
// 限制每秒转向的角度
if (yaogan.kg) {
if (Math.abs(yaogan.jiaodu - snake.jiaodu)<180) {
if (yaogan.jiaodu - snake.jiaodu>0) {
snake.jiaodu +=120*modifier
}
if (yaogan.jiaodu - snake.jiaodu<0) {
snake.jiaodu -=120*modifier
}
}
if (Math.abs(yaogan.jiaodu - snake.jiaodu)>180) {
if (yaogan.jiaodu - snake.jiaodu>0) {
snake.jiaodu -=120*modifier
}
if (yaogan.jiaodu - snake.jiaodu<0) {
snake.jiaodu +=120*modifier
}
}
if (snake.jiaodu>360) {
snake.jiaodu -= 360
}
if (snake.jiaodu<0) {
snake.jiaodu += 360
}
}

// 限制摇杆出去
var absx = Math.abs(yaogan.click.x-yaogan.dot.x)
var absy = Math.abs(yaogan.click.y-yaogan.dot.y)
if (Math.sqrt(Math.pow(absx,2)+Math.pow(absy,2)).toFixed(1)<(yaogan.r-yaogan.gan.r) ) {
yaogan.gan.x = yaogan.click.x
yaogan.gan.y = yaogan.click.y
} else {
yaogan.gan.x = yaogan.dot.x - Math.floor((yaogan.r-yaogan.gan.r)*Math.sin( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))
yaogan.gan.y = yaogan.dot.y + Math.floor((yaogan.r-yaogan.gan.r)*Math.cos( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))
// if (x > yaogan.dot.x && y > yaogan.dot.y) {
// //那么角度在0到90之间
// yaogan.gan.x = 0.yaogan.dot.x - Math.floor(yaogan.r*Math.sin( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))
// yaogan.gan.y = Math.floor(yaogan.r*Math.cos( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))+ yaogan.dot.y
// }
// if (x < yaogan.dot.x && y > yaogan.dot.y) {
// //那么角度在90到180之间
// yaogan.gan.x = yaogan.dot.x - Math.floor(yaogan.r*Math.sin( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))
// yaogan.gan.y = Math.floor(yaogan.r*Math.cos( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))+ yaogan.dot.y
// }
// if (x < yaogan.dot.x && y < yaogan.dot.y) {
// //那么角度在180到270之间
// yaogan.gan.x = yaogan.dot.x - Math.floor(yaogan.r*Math.sin( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))
// yaogan.gan.y = Math.floor(yaogan.r*Math.cos( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))+ yaogan.dot.y
// }
// if (x > yaogan.dot.x && y < yaogan.dot.y) {
// //那么角度在0到90之间
// yaogan.gan.x = yaogan.dot.x - Math.floor(yaogan.r*Math.sin( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))
// yaogan.gan.y = Math.floor(yaogan.r*Math.cos( Math.PI*(yaogan.jiaodu-90)/180).toFixed(5))+ yaogan.dot.y
// }
}

// 更新蛇头牵引坐标
snake.x += snake.speed * modifier * Math.cos( Math.PI*snake.jiaodu/180).toFixed(5)
snake.y += snake.speed * modifier * Math.sin( Math.PI*snake.jiaodu/180).toFixed(5)
// snake.x = Math.abs(snake.x)
// snake.y = Math.abs(snake.y)
// 限制多余坐标
if (Math.abs(Math.floor(snake.x) - snake.body[0].x) >1 || Math.abs(Math.floor(snake.y) - snake.body[0].y) >1) {
snake.body.unshift({x:Math.floor(snake.x),y:Math.floor(snake.y)})
}
if (snake.body.length > snake.snakeLength) {
snake.body.pop()
}
// console.dir("x="+snake.body[0].x+"&y="+snake.body[0].y)

// 得到蛇的坐标变化
ditu.item.x = snake.body[0].x - canvas.width/2;
ditu.item.y = snake.body[0].y - canvas.height/2;

// for (var i in snake.body) {
// if (i != 0) {
// snake.body[i].x = snake.body[i].x + x
// snake.body[i].y = snake.body[i].y + y
// }
// }
// console.dir("x="+x+"&y="+y)
// 更新地图
// ditu.canzhao.x = ditu.canzhao.x + (snake.body[0].x - canvas.width/2);
// ditu.canzhao.y = ditu.canzhao.y + (snake.body[0].y - canvas.height/2);

// ditu.arr
};

// 画出所有物体
var render = function () {
{
// 画背景
context.beginPath()
context.fillStyle = "white"
context.fillRect(0,0,canvas.width,canvas.height);
context.closePath();

for (var i = 0; i < ditu.arr.length; i++) {
context.beginPath()
context.fillStyle = ditu.arr[i].color
context.arc(ditu.arr[i].x - ditu.item.x, ditu.arr[i].y - ditu.item.y, 30 , 0 , 2*Math.PI)
context.fill()
}

}
// 绘制蛇
context.beginPath()
context.moveTo(snake.body[0].x - ditu.item.x,snake.body[0].y - ditu.item.y)
for (var i in snake.body) {
// for (var i =0 ; i<snake.body.length ; i++) {
if (i>0) {
context.lineTo(snake.body[i].x - ditu.item.x , snake.body[i].y - ditu.item.y)
}
}
context.lineCap = "round";
context.lineJoin = "round";
context.lineWidth = snake.r*2
context.strokeStyle = "#66ccff";
context.stroke();
context.closePath()
// 绘制蛇头
context.beginPath()
context.fillStyle = "red"
context.arc(snake.body[0].x - ditu.item.x, snake.body[0].y - ditu.item.y, snake.r , 0 , 2*Math.PI)
context.fill()
context.closePath()

// 绘制摇杆的圈
context.beginPath()
context.fillStyle = 'rgba(204, 204, 204, 0.7)'
context.arc( yaogan.dot.x, yaogan.dot.y, 60 , 0 , 2*Math.PI)
context.fill()
context.closePath()

context.beginPath()
context.fillStyle = 'rgba(0, 0, 0, 0.5)'
context.arc( yaogan.gan.x, yaogan.gan.y, yaogan.gan.r , 0 , 2*Math.PI)
context.fill()
context.closePath()

if (yaogan.kg) {
// 显示参数
context.beginPath();
context.font="30px Arial";
context.fillStyle="red";
// context.fillText("x:"+Math.floor(yaogan.gan.x)+";y:"+Math.floor(yaogan.gan.y)+";角度:"+snake.jiaodu,10,50);
context.fillText("x:"+Math.floor(snake.x)+";y:"+Math.floor(snake.y)+";角度:"+snake.jiaodu,10,50);
context.closePath()

}

};
// 游戏主函数
var main = function () {
var now = Date.now();
var delta = now - then;

update(delta / 1000);
panduanjiaodu()
render();

then = now;
// 立即调用主函数
requestAnimationFrame(main);
};
// requestAnimationFrame 的浏览器兼容性处理
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
var then = Date.now();
main();
}

贪吃蛇大作战canvas实现(手机触屏操作)--地图逻辑的更多相关文章

  1. Unity3D游戏贪吃蛇大作战源码休闲益智手机小游戏完整项目

    <贪吃蛇大作战>一款休闲竞技游戏,不仅比拼手速,更考验玩家的策略. 视频演示: http://player.youku.com/player.php/sid/XMzc5ODA2Njg1Ng ...

  2. unity3d触屏操作对象运动

    using UnityEngine; using System.Collections; public class robot : MonoBehaviour { private GameObject ...

  3. HTML5学习总结-09 拖放和手机触屏事件

    一 拖放 拖放(Drag 和 drop)是 HTML5 标准的组成部分.拖放是一种常见的特性,即抓取对象以后拖到另一个位置.在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. 课程参考 ht ...

  4. jQuery手机触屏拖动滑块验证跳转插件

    HTML: <!DOCTYPE html> <html lang="en"> <head> <title>jQuery手机触屏拖动滑 ...

  5. 手机触屏滑动图片切换插件swiper.js

    今天给大家分享一款手机触屏滑动图片切换插件swiper.js是一款swiper手机触屏滑动图片幻灯片,适合各种尺寸.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div ...

  6. WPF Multi-Touch 开发:基础触屏操作(Raw Touch)

    原文 WPF Multi-Touch 开发:基础触屏操作(Raw Touch) 多点触控(Multi-Touch)就是通过与触屏设备的接触达到人与应用程序交互的操作过程.例如,生活中经常使用的触屏手机 ...

  7. WPF Multi-Touch 开发:高级触屏操作(Manipulation)

    原文 WPF Multi-Touch 开发:高级触屏操作(Manipulation) 在上一篇中我们对基础触控操作有了初步了解,本篇将继续介绍触碰控制的高级操作(Manipulation),在高级操作 ...

  8. 手机触屏的js事件

    处理Touch事件能让你跟踪用户的每一根手指的位置.你可以绑定以下四种Touch事件:     1.touchstart:  // 手指放到屏幕上的时候触发      2.touchmove:  // ...

  9. 基于appium的模拟单点或多点触屏操作

    一.单点触控 TouchAction类:将一系列的动作放在一个链条中,然后将该链条传递给服务器,服务器接受该链条后,解析各个动作,逐个执行,TouchAction类提供了以下几种方法: 短按:pres ...

随机推荐

  1. WPF的DataTrigger使用

    首先创建一个空的项目 然后看看前台写的代码,如下图所示 <Grid> <StackPanel HorizontalAlignment="Center" Verti ...

  2. 信号量Semaphore实现原理

    Semaphore用于管理信号量,在并发编程中,可以控制返访问同步代码的线程数量.Semaphore在实例化时传入一个int值,也就是指明信号数量.主要方法有两个:acquire()和release( ...

  3. Scrapy抓取jobbole数据

    1.python版本3.6.1 2.python编辑器:JetBrains PyCharm 2.安装virtualenvwrapper-win pip3 install virtualenvwrapp ...

  4. .net Console.ReadLine无效

    代码中出现了 Console.ReadLine无效解决办法:把应用程序的输出类型改为 控制台应用程序

  5. ACM-ICPC 2015 Changchun Preliminary Contest J. Unknown Treasure (卢卡斯定理+中国剩余定理)

    题目链接:https://nanti.jisuanke.com/t/A1842 题目大意:给定整数n,m,k,其中1≤m≤n≤1018,k≤10, 然后给出k个素数,保证M=p[1]*p[2]……*p ...

  6. css--图片整合(精灵图)

    图片整合(精灵图) 精灵图的优点: 减少图片的字节 减少了网页的http请求,从而大大的提高了页面的性能 解决了网页设计师在图片命名上的困扰,只需对一张集合的图片上命名就可以了,不需要对每一个小元素进 ...

  7. GC、进程和线程的定义

    GC是什么,为什么要有GC GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃.Java提供的GC ...

  8. 两个list 合并后去除掉重复removeAll()的,然后再随机获取最后list中的 几个值

    public static void test1(){ String s1="1,2,5,3,6,9"; String n1[]=s1.split(","); ...

  9. Android解析编译之后的所有文件(so,dex,xml,arsc)格式

    我们在之前一篇一篇介绍了如何解析Android中编译之后的所有文件格式,所有的工作都完成了,这里我们就来做个总结,我们为什么要做这些工作: 第一篇:解析so文件格式 点击进入 这里我们解析so文件,主 ...

  10. Java并发指南14:JUC中常用的Unsafe和Locksupport

    本文转自网络,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutoria ...