贪吃蛇大作战canvas实现(手机触屏操作)--地图逻辑
//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实现(手机触屏操作)--地图逻辑的更多相关文章
- Unity3D游戏贪吃蛇大作战源码休闲益智手机小游戏完整项目
<贪吃蛇大作战>一款休闲竞技游戏,不仅比拼手速,更考验玩家的策略. 视频演示: http://player.youku.com/player.php/sid/XMzc5ODA2Njg1Ng ...
- unity3d触屏操作对象运动
using UnityEngine; using System.Collections; public class robot : MonoBehaviour { private GameObject ...
- HTML5学习总结-09 拖放和手机触屏事件
一 拖放 拖放(Drag 和 drop)是 HTML5 标准的组成部分.拖放是一种常见的特性,即抓取对象以后拖到另一个位置.在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. 课程参考 ht ...
- jQuery手机触屏拖动滑块验证跳转插件
HTML: <!DOCTYPE html> <html lang="en"> <head> <title>jQuery手机触屏拖动滑 ...
- 手机触屏滑动图片切换插件swiper.js
今天给大家分享一款手机触屏滑动图片切换插件swiper.js是一款swiper手机触屏滑动图片幻灯片,适合各种尺寸.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div ...
- WPF Multi-Touch 开发:基础触屏操作(Raw Touch)
原文 WPF Multi-Touch 开发:基础触屏操作(Raw Touch) 多点触控(Multi-Touch)就是通过与触屏设备的接触达到人与应用程序交互的操作过程.例如,生活中经常使用的触屏手机 ...
- WPF Multi-Touch 开发:高级触屏操作(Manipulation)
原文 WPF Multi-Touch 开发:高级触屏操作(Manipulation) 在上一篇中我们对基础触控操作有了初步了解,本篇将继续介绍触碰控制的高级操作(Manipulation),在高级操作 ...
- 手机触屏的js事件
处理Touch事件能让你跟踪用户的每一根手指的位置.你可以绑定以下四种Touch事件: 1.touchstart: // 手指放到屏幕上的时候触发 2.touchmove: // ...
- 基于appium的模拟单点或多点触屏操作
一.单点触控 TouchAction类:将一系列的动作放在一个链条中,然后将该链条传递给服务器,服务器接受该链条后,解析各个动作,逐个执行,TouchAction类提供了以下几种方法: 短按:pres ...
随机推荐
- 命令行运行python -m http.server报错
最近在学习网站搭建,借助python搭建服务器时,在网站目录启动python服务时报错,如下: UnicodeDecodeError: 'utf-8' codec can't decode byte ...
- express 设置允许跨域访问
//demo const express = require('express'); const app = express(); //设置允许跨域访问该服务. app.all(’’, functio ...
- left join on and和left join on where条件的困惑[转]
外连接:left join(左联接) left outer join 返回包括左表中的所有记录和右表中联结字段相等的记录right join(右联接) right outer join返回包括右表中的 ...
- python基础--内置函数filter,reduce
movie_people=["sb+_alex","sb_wupeiqi","han"] # def filter_test(array): ...
- 客户端模拟线程线程池发送100个文件给socket
1.线程池模拟发送100个线程发送 2.每个线程启动一个socket发送文件 3.线程池最大并发几个
- Java反编译工具Luyten-0.5.3
Luyten是一款很强大的反编译工具包,是一款github的开源工具,软件功能非常强大,界面简洁明晰.操作方便快捷,设计得很人性化. 工具软件下载路径:https://github.com/death ...
- Codeforces Round #595 (Div. 3) 题解
前言 大家都在洛谷上去找原题吧,洛谷还是不错的qwq A 因为没有重复的数,我们只要将数据排序,比较两两之间有没有\(a_j - a_i == 1 (j > i)\) 的,有则输出 \(2\) ...
- SpringBoot 利用freemaker生成静态页面
1. <!-- freemarker模板 --> <dependency> <groupId>org.springframework.boot</groupI ...
- 微服务+DDD代码结构例子
这是一个基本的微服务+DDD演示例子: 基于 Spring Boot 1.5.6 , Spring Cloud Edgware.SR4 Version 微服务 + DDD,个人觉得应该是首先是从微服务 ...
- Flask之路由相关
1.装饰器中的参数 @app.route("/info", methods=["GET", "POST"]) def student_inf ...